相关疑难解决方法(0)

Haskell:什么是弱头正常形式?

什么是弱头范式(WHNF)是什么意思?什么是头标准型(HNF)和范式(NF)是什么意思?

真实世界Haskell说:

熟悉的seq函数将表达式计算为我们称之为head normal form(缩写为HNF)的表达式.它一旦到达最外面的构造函数("头部")就会停止.这与正常形式(NF)不同,其中表达式被完全评估.

您还将听到Haskell程序员引用弱头正常形式(WHNF).对于正常数据,弱头正常形式与头部正常形式相同.差异只出现在功能上,而且我们在这里无关紧要.

我已经阅读了一些资源和定义(Haskell WikiHaskell邮件列表自由词典),但我没有得到它.有人可能举一个例子或提供外行定义吗?

我猜它会类似于:

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吗?

常见的新手堆栈溢出代码:

myAverage = uncurry (/) . foldl' (\(acc, len) x -> (acc+x, len+1)) (0,0)
Run Code Online (Sandbox Code Playgroud)

了解seq和弱头正常形式(whnf)的人可以立即明白这里出了什么问题.(acc + x,len + 1)已经在whnf中,所以seq将值减少到whnf,对此无效.这段代码将像原始的foldl示例一样构建thunks,它们只是在元组内部.解决方案只是强制元组的组件,例如

myAverage …
Run Code Online (Sandbox Code Playgroud)

haskell definition strictness weak-head-normal-form

279
推荐指数
6
解决办法
3万
查看次数

严格声明有什么意义?

我正在启动Haskell并且正在查看一些使用"!"定义数据类型的库.bytestring库中的示例:

data ByteString = PS {-# UNPACK #-} !(ForeignPtr Word8) -- payload
                     {-# UNPACK #-} !Int                -- offset
                     {-# UNPACK #-} !Int                -- length
Run Code Online (Sandbox Code Playgroud)

现在我看到这个问题是对这意味着什么的解释,我想这很容易理解.但我现在的问题是:使用它有什么意义?由于表达式将在需要时进行评估,为什么要强制进行早期评估?

在这个问题的第二个答案中,CV汉森说:"[...]有时懒惰的开销可能太多或浪费".这是否意味着它用于节省内存(保存值比保存表达式便宜)?

一个解释和一个例子将是伟大的!

谢谢!

[ 编辑 ]我想我应该选择一个没有{ - #UNPACK# - }的例子.所以让我自己做一个.这会有意义吗?是的,为什么以及在什么情况下?

data MyType = Const1 !Int
            | Const2 !Double
            | Const3 !SomeOtherDataTypeMaybeMoreComplex
Run Code Online (Sandbox Code Playgroud)

haskell lazy-evaluation

11
推荐指数
1
解决办法
341
查看次数