有两种方法来评估的表达式:
- 懒惰(评价最外侧的第一)。
- 严格(评估最里面的第一个)。
考虑下面的函数:
select x y z = if x > z then x else y
现在,让我们把它叫做:
select (2 + 3) (3 + 4) (1 + 2)
这将如何进行评估?
严格评价:评价最里面的第一个。
select (2 + 3) (3 + 4) (1 + 2)
select 5 (3 + 4) (1 + 2)
select 5 7 (1 + 2)
select 5 7 3
if 5 > 3 then 5 else 7
if True then 5 else 7
5
严格的评估花了6个减少。要评估select
我们首先必须评估它的论点。在严格评估中,函数的参数总是被充分评估。因此功能是“按价值调用”。因此没有额外的簿记。
懒惰评价:评价最外面的第一个。
select (2 + 3) (3 + 4) (1 + 2)
if (2 + 3) > (1 + 2) then (2 + 3) else (3 + 4)
if 5 > (1 + 2) then 5 else (3 + 4)
if 5 > 3 then 5 else (3 + 4)
if True then 5 else (3 + 4)
5
懒惰评价只需要5减少。我们从未使用过(3 + 4)
,因此我们从未评估过它。在懒惰评估中,我们可以评估一个函数而不用评估它的参数。参数只在需要时才被评估。因此功能是“按需呼叫”。
然而,“按需呼叫”评估策略需要额外的簿记 - 您需要跟踪是否评估了表达式。在上述表达式中,当我们评估x = (2 + 3)
时,我们不需要再次评估它。但是,我们确实需要跟踪它是否得到评估。
Haskell支持严格和懒惰的评估。但是它默认支持懒评估。要启用严格的评估,您必须使用特殊功能seq
和deepSeq
。
同样,您可以在JavaScript等严格语言中进行懒惰评估。但是,您需要跟踪表达式是否已经过评估。你可以研究用JavaScript或类似语言实现thunk。