在Haskell中seq与rnf

时间:2017-08-16 15:31:07

标签: haskell

根据" Haskell中的并行和并发编程"给出的定义。在第29页,类方法"返回正常形式"定义为:

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]

作者是否犯了一个明显的错误,或者我在这里遗漏了什么?

编辑:我意识到我的原始问题包含基本错误。这是问题的正确形式。

1 个答案:

答案 0 :(得分:3)

  

也许,通过在类中声明实现,可以说这是默认实现,除非在特定实例声明中另有说明?

是的,这正是它的含义。什么是不寻常的(IMO)通常这个默认实现对所有实例都有效(即做你想要的),但可能会被覆盖以提高效率或打破默认定义的循环(例如在Eq中默认实现是x == y = not (x /= y)x /= y = not (x == y),因此您可以覆盖哪个更方便。

但如果是rnfthe documentation for 1.3.0.0

  
    

在为没有未评估字段(例如枚举)的数据类型定义实例时,rnf的默认实现可能很方便。

  

即。它几乎不适用于所有类型。

此问题已修复since 1.4.0.0