3 回答
TA贡献1804条经验 获得超3个赞
Haskell中关于Thunks和Weak Head Normal Form的部分Wikibooks 对懒惰的描述提供了对WHNF的非常好的描述以及这个有用的描述:
逐步评估值(4,[1,2])。第一阶段完全没有评估; 所有后续表格都在WHNF中,最后一个表格也是正常形式。
TA贡献1836条经验 获得超3个赞
Haskell程序是表达式,它们通过执行评估来运行。
要评估表达式,请按其定义替换所有函数应用程序。你这样做的顺序并不重要,但它仍然很重要:从最外面的应用程序开始,从左到右进行; 这称为懒惰评估。
例:
take 1 (1:2:3:[])=> { apply take } 1 : take (1-1) (2:3:[])=> { apply (-) } 1 : take 0 (2:3:[])=> { apply take } 1 : []
当没有更多功能应用程序需要更换时,评估停止。结果是正常形式(或缩小的正常形式,RNF)。无论您评估表达式的顺序如何,您总是会以相同的正常形式结束(但仅在评估终止时)。
懒惰评估的描述略有不同。也就是说,它表示你应该只评估所有的弱头正常形式。在WHNF中,表达式恰好有三种情况:
构造函数:
constructor expression_1 expression_2 ...
一个内置函数,参数太少,比如
(+) 2
或sqrt
lambda表达式:
\x -> expression
换句话说,表达式的头部(即最外面的函数应用程序)不能再进一步求值,但函数参数可能包含未评估的表达式。
WHNF的例子:
3 : take 2 [2,3,4] -- outermost function is a constructor (:)(3+1) : [4..] -- ditto\x -> 4+5 -- lambda expression
笔记
WHNF中的“头”不是指列表的头部,而是指最外层的函数应用程序。
有时候,人们会将未评价的表达称为“thunk”,但我认为这不是理解它的好方法。
头部正规形式(HNF)与Haskell无关。它与WHNF的不同之处在于,lambda表达式的实体也在某种程度上得到了评估。
添加回答
举报