什么是弱头范式(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 : []
Run Code Online (Sandbox Code Playgroud)
如何做seq
和($!)
与WHNF和HNF有关?
我还是很困惑.我知道有些答案会忽略HNF.通过阅读各种定义,似乎WHNF和HNF中的常规数据之间没有区别.但是,它似乎与功能有所区别.如果没有差异,为什么还seq
需要foldl'
?
另一个混淆点来自Haskell Wiki,它指出seq
减少到WHNF,并且对以下示例不做任何处理.然后他们说他们必须seq
用来强迫评估.那不是强迫它到HNF吗?
常见的新手堆栈溢出代码:
Run Code Online (Sandbox Code Playgroud)myAverage = uncurry (/) . foldl' (\(acc, len) x -> (acc+x, len+1)) (0,0)
了解seq和弱头正常形式(whnf)的人可以立即明白这里出了什么问题.(acc + x,len + 1)已经在whnf中,所以seq将值减少到whnf,对此无效.这段代码将像原始的foldl示例一样构建thunks,它们只是在元组内部.解决方案只是强制元组的组件,例如
Run Code Online (Sandbox Code Playgroud)myAverage …
我不完全确定如何问这个,但有没有办法显示一个thunk的结构?
例如
f x = x + 2
g x = 3 x
compo x = f (g x)
ans = compo 5
-- result: (3 * 5) + 2 = 17
Run Code Online (Sandbox Code Playgroud)
有什么方法可以"看到"thunk ans
吗?就像在,我可以看到β减少的过程compo
或像"一般"形式.
我想看看,例如:
compo n
--> (3 * n) + 2
Run Code Online (Sandbox Code Playgroud)
就像在,如果我有一个函数compo x
,我想看到它被分解为(3*n)+2
.
例如,在Mathematica中:
f[x_] := x+2;
g[x_] := 3*x;
compo[x_] := f[g[x]];
compo[n]
(%
--> (3 * n) + 2
%)
Run Code Online (Sandbox Code Playgroud)