[英]How does the outermost evaluation strategy evaluate partial application of a function and application of a curried function
[英]How does outermost evaluation work on an application of a curried function?
mult
被定义为咖喱函数:
mult :: Int -> Int -> Int
mult x = \y -> x * y
mult (1+2) (2+3)
mult(1+2)
, 1+2
和2+3
吗? 2+3
吗? 根据赫顿的《 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
谢谢。
多重mult (1+2) (2+3)
最外面的redex
mult
/ \
+ +
1 2 2 3
是mult xy
,其中x = (1+2)
和y = (2+3)
。
有两个内部redexe, (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
写下解析树:
o
/ \
o o
/ \ /|\
mult o 2 + 3
/|\
1 + 2
(为简单起见,我将二进制中缀+
运算符视为单个应用程序,它也可能是((+) 1) 2
)
现在,最外层的函数应用程序是参数2+3
的mult (1+2)
,但是由于函数不是单个值而是应用程序本身,因此无法归约。 我们必须首先评估:
(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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.