鉴于这一行Haskell代码,我的任务是将其评估为最简单的形式。
let g h k = (\x -> k (h x)) in g (+1) (\x -> x+x) 20
我已经得到了答案(当然在GHCI中自己评估过):42
但是,我想更好地了解评估在这里的实际运作方式。一般来说,我想我知道如何(简单)让表达式起作用:
实施例
a = let y = 5 in y * 5 -- a == 25
此评估结果为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
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
但令我困惑的是在let之后使用g h k
。这是什么意思?
答案 0 :(得分:10)
考虑一个函数定义。如果你写:
g h k x = k (h x)
然后它是一个函数,它接受三个参数h
,k
和x
并返回k (h x)
。这相当于:
g h k = \x -> k (h x)
或:
g h = \k x -> k (h x)
或:
g = \h k x -> k (h x)
因此我们可以在函数的头部和body中的lambda表达式之间传递变量。实际上,Haskell编译器会重写它。
因此,使用let
表达式,我们定义了一个局部范围的函数,就像上面定义的那样。现在,如果我们拨打g (+1) (\x -> x+x) 20
,则会g
,h = (+1)
和k = (\x -> x+x)
致电x = 20
。
所以我们将其评估为:
(\x -> x+x) ((+1) 20)
评估为:
(\x -> x+x) ((+1) 20)
-> ((+1) 20)+((+1) 20)
-> 21 + 21
-> 42
答案 1 :(得分:8)
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