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
=21
k (h 20)
= k 21
= 21 + 21
=42
但让我感到困惑的是使用g h k
let之后.那是什么意思?
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 次 |
最近记录: |