什么是弱头标准型(WHNF) ?Head Normal form (HNF)和Normal form (NF)是什么意思?
Real World Haskell声明:
我们熟悉的seq函数将表达式求值为 呼叫头标准型(简称HNF)。它一旦到达就会停止 最外层的构造函数(“head”)。这与正常情况不同 形式(NF),其中表达式被完全求值。 您还会听到Haskell程序员提到弱头正常 表单(WHNF)。对于正规数据,弱头正规形式与 头部正常形式。这种差异只出现在函数中,也是如此 这里涉及到我们的深奥。
我读了一些资源和定义(Haskell维基和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吗?
Common newbie stack overflowing code: myAverage = uncurry (/) . foldl' (\(acc, len) x -> (acc+x, len+1)) (0,0) People who understand seq and weak head normal form (whnf) can immediately understand what goes wrong here. (acc+x, len+1) is already in whnf, so the seq (in the definition of foldl'), which reduces a value to whnf, does nothing to this. This code will build up thunks just like the original foldl example, they'll just be inside a tuple. The solution is just to force the components of the tuple, e.g. myAverage = uncurry (/) . foldl' (\(acc, len) x -> acc `seq` len `seq` (acc+x, len+1)) (0,0)
-Haskell Wiki在Stackoverflow上