什么是弱头正常形式?
什么是弱头范式(WHNF)是什么意思?什么是头标准型(HNF)和范式(NF)是什么意思?
熟悉的seq函数将表达式计算为我们称之为head normal form(缩写为HNF)的表达式。它一旦到达最外面的构造函数(“头部”)就会停止。这与正常形式(NF)不同,其中表达式被完全评估。
您还将听到Haskell程序员引用弱头正常形式(WHNF)。对于正常数据,弱头正常形式与头部正常形式相同。差异只出现在功能上,而且我们在这里无关紧要。
我已经阅读了一些资源和定义(Haskell Wiki和Haskell邮件列表和自由词典),但我没有得到它。有人可能举一个例子或提供外行定义吗?
我猜它会类似于:
WHNF = thunk : thunk HNF = 0 : thunk NF = 0 : 1 : 2 : 3 : []
如何做seq
和($!)
与WHNF和HNF有关?
我还是很困惑。我知道有些答案会忽略HNF。通过阅读各种定义,似乎WHNF和HNF中的常规数据之间没有区别。但是,它似乎与功能有所区别。如果没有差异,为什么还seq
需要foldl'
?
另一个混淆点来自Haskell Wiki,它指出seq
减少到WHNF,并且对以下示例不做任何处理。然后他们说他们必须seq
用来强制评估。那不是强迫它到HNF吗?
常见的新手堆栈溢出代码:
myAverage = uncurry (/) . foldl' (\(acc, len) x -> (acc+x, len+1)) (0,0)了解seq和弱头正常形式(whnf)的人可以立即理解这里出了什么问题。(acc + x,len + 1)已经在whnf中,所以seq将值减少到whnf,对此无效。这段代码将像原始的foldl示例一样构建thunks,它们只是在元组内部。解决方案只是强制元组的组件,例如
myAverage = uncurry (/) . foldl' (\(acc, len) x -> acc `seq` len `seq` (acc+x, len+1)) (0,0)
狐的传说
米脂
相关分类