Haskell 的评估是懒惰的:它通过最左边的redex 策略进行(至少在概念上):它减少最左边的 redex 中的最左边。
大概head
定义为
head xs = case xs of (x:_) -> x
那么它对任何表达式的应用确实是一个redex——一个需要归约的表达式。根据 的定义进行head
,
head (map (+1) (3:repeat 3))
=
case (map (+1) (3:repeat 3)) of (x:_) -> x
=
(或者我们可以说它head
本身是最左上角的 redex,它首先简化为它的定义;如果我们写上面的内容,((\xs -> case xs of (x:_) -> x) (map (+1) (3:repeat 3)))
我们会得到相同的结果,只是有点乏味)。
一个主要的强制原语是case
. 现在它需要执行模式匹配,因此它必须找出其检查表达式的值(仅在模式匹配成为可能的范围内)。要做到这一点,它现在必须根据其定义工作map
,大概是
map f xs = case xs of { (x:ys) -> f x : map f ys
; [] -> [] }
所以它变成
case (map (+1) (3:repeat 3)) of (x:_) -> x
=
case (case (3:repeat 3) of
{ (x:ys ) -> (+1) x : map (+1) ys
; [] -> [] } )
of (x:_) -> x
=
此时可以减少内心的case
表达,
case (let { x=3 ; ys=repeat 3} in
(+1) x : map (+1) ys )
of (x : _ ) -> x
=
现在outer case
的模式匹配成为可能,
case (let { x=3 } in
(+1) x )
of (x ) -> x
=
let { x=3 } in
(+1) x
=
(+1) 3
=
4