unn*_*olo 10 lambda haskell anonymous-function let expression-evaluation
鉴于这一系列的Haskell代码,我的任务是将其评估为最简单的形式.
let g h k = (\x -> k (h x)) in g (+1) (\x -> x+x) 20
Run Code Online (Sandbox Code Playgroud)
我已经得到了答案(当然在GHCI中我自己进行了评估): 42
但是,我希望更好地了解评估在这里如何运作.一般来说,我想我知道如何(简单)让表达式工作:
例
a = let y = 5 in y * 5 -- a == 25
Run Code Online (Sandbox Code Playgroud)
该计算结果为25,因为我们绑定y到的价值5和a被分配到的值y*5(后部分in).绑定y = 5仅在范围内有效let.
到目前为止,唯一的解释(至少评估为42)如下:
let g h k = (\x -> k (h x)) in g (+1) (\x -> x+x) 20
Run Code Online (Sandbox Code Playgroud)
g 是 (\x -> k (h x))h是(+1)(功能(\x -> x+1))k 是 (\x -> x+x)
20是g收益的输入k (h 20)h 20给20 + 1=21k (h 20)= k 21= 21 + 21=42但让我感到困惑的是使用g h klet之后.那是什么意思?
Wil*_*sem 10
想一下函数定义.如果你写:
g h k x = k (h x)
Run Code Online (Sandbox Code Playgroud)
然后,它是一个有三个参数的函数h,k并x返回k (h x).这相当于:
g h k = \x -> k (h x)
Run Code Online (Sandbox Code Playgroud)
要么:
g h = \k x -> k (h x)
Run Code Online (Sandbox Code Playgroud)
要么:
g = \h k x -> k (h x)
Run Code Online (Sandbox Code Playgroud)
因此,我们可以在函数的头部和正文中的lambda表达式之间传递变量.实际上,Haskell编译器会重写它.
因此,使用let表达式,我们定义了一个局部范围的函数,就像上面定义的那样.现在,如果我们调用g (+1) (\x -> x+x) 20,然后将因此打电话g与h = (+1),k = (\x -> x+x)和x = 20.
所以我们将其评估为:
(\x -> x+x) ((+1) 20)
Run Code Online (Sandbox Code Playgroud)
其评估结果为:
(\x -> x+x) ((+1) 20)
-> ((+1) 20)+((+1) 20)
-> 21 + 21
-> 42
Run Code Online (Sandbox Code Playgroud)
g h k = ...是一个函数定义.这意味着应用于g两个参数(命名h和k)的结果将评估该...部分.换句话说,它是一个捷径g = \h -> \k -> ....
所以我们可以按步骤简化表达式,如下所示:
let g h k = (\x -> k (h x)) in g (+1) (\x -> x+x) 20
let g = \h -> \k -> (\x -> k (h x)) in g (+1) (\x -> x+x) 20
(\h -> \k -> (\x -> k (h x))) (+1) (\x -> x+x) 20
(\k -> (\x -> k ((+1) x))) (\x -> x+x) 20
(\x -> (\x -> x+x) ((+1) x)) 20
(\x -> x+x) ((+1) 20)
(\x -> x+x) 21
21 + 21
42
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
318 次 |
| 最近记录: |