mult
被定义为咖喱函数:
mult :: Int -> Int -> Int
mult x = \y -> x * y
在mult (1+2) (2+3)
中,
mult(1+2)
,1+2
和2+3
吗? 2+3
吗?根据赫顿(Hutton)在《 Haskell编程》中的描述,最内层的评估对表达式进行如下操作:
mult (1+2) (2+3)
= { applying the first + }
mult 3 (2+3)
= { applying mult }
(\y -> 3 * y) (2+3)
= { applying + }
(\y -> 3 * y) 5
= { applying the lambda }
3 * 5
= { applying * }
15
对mult (1+2) (2+3)
的最外部评估如何工作?
最外面的评估工作如下吗?
mult (1+2) (2+3)
= mult (1+2) 5
= (\y -> (1+2) * y) 5
= (1+2) * 5 // Is (1+2) evaluated before (1+2) * 5, because builtin function "*" is strict, i.e. application of builtin function always happen after evaluation of its args?
= 3*5
= 15
谢谢。
答案 0 :(得分:1)
mult (1+2) (2+3)
中最外面的redex,即
mult
/ \
+ +
1 2 2 3
是mult x y
,其中x = (1+2)
和y = (2+3)
。
有两个内部Redex,(1+2)
和(2+3)
。因此,最里面的最左端的redex是(1+2)
。
通过最左边的redex进行还原的过程如下:
mult (1+2) (2+3)
=
mult 3 (2+3)
=
mult 3 5
= {- mult x = \y -> x * y -}
(let x = 3 in (\y -> x * y)) 5
=
let x = 3 in let y = 5 in x * y
=
3 * 5
=
15
减少最高的redex的过程如下:
mult (1+2) (2+3)
= {- mult x = \y -> x * y -}
(let x = (1+2) in (\y -> x * y)) (2+3)
=
let x = (1+2) in let y = (2+3) in x * y
=
(1+2) * (2+3)
=
3 * (2+3)
=
3 * 5
=
15
答案 1 :(得分:1)
写下分析树:
o
/ \
o o
/ \ /|\
mult o 2 + 3
/|\
1 + 2
(为简单起见,我将二进制中缀+
运算符视为单个应用程序,也可能是((+) 1) 2
)
现在最外层的函数应用程序是mult (1+2)
到参数2+3
的函数,但是由于函数不是单个值而是应用程序本身,因此它不可简化。我们必须先对此进行评估:
(mult (1+2)) (2+3)
((\x->\y->x*y) (1+2)) (2+3) -- the value that `mult` refers to
(\y->(1+2)*y) (2+3) -- evaluate the application of `\x->`
现在我们可以评估根函数应用程序了:
(1+2) * (2+3) -- application of `\y->`
现在最外面的表达式是*
,但是您知道这些整数运算符很严格,因此它们需要首先评估其参数(从左到右,IIRC):
3 * (2+3)
3 * 5
15