[英]seq vs. rnf in Haskell
根据第29页上的“Haskell中的并行和并发编程”给出的定义,类方法“返回普通形式”定义为:
rnf a = a `seq` ()
只是为了看看是否在另一个函数中包装seq,正如作者所规定的那样,确实有强制'a'被评估为正常形式的结果,我尝试自己实现该函数并得到否定的结果:
Prelude Control.DeepSeq > myrnf a = a `seq` ()
Prelude Control.DeepSeq > xs = map (+1) [1..10] :: [Int]
Prelude Control.DeepSeq > :sprint xs
xs = _
Prelude Control.DeepSeq > myrunf xs
()
Prelude Control.DeepSeq > :sprint xs
xs = _ : _
Prelude Control.DeepSeq > rnf xs
()
Prelude Control.DeepSeq > :sprint xs
xs = [2,3,4,5,6,7,8,9,10,11]
那么作者是否犯了一个明显的错误,或者我错过了什么?
编辑:我意识到我的原始问题包含基本错误。 这是问题的正确形式。
也许,通过在类中声明实现,可以说这是默认实现,除非在特定实例声明中另有说明?
是的,这正是它的意思。 有什么不寻常的(IMO)通常这个默认实现对所有实例都有效(即做你想要的),但可能会被覆盖以提高效率或打破默认定义的循环(例如,在Eq
,默认实现是x == y = not (x /= y)
和x /= y = not (x == y)
,所以你可以覆盖哪个更方便)。
但是在rnf
情况下, rnf
的文档说
在为没有未评估字段(例如枚举)的数据类型定义实例时,
rnf
...的默认实现可能很方便。
即它几乎不适用于所有类型。
自1.4.0.0以来,此问题已得到修复。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.