Haskell:seq,par,rseq,rpar签名

时间:2016-10-27 09:20:05

标签: haskell

我正在尝试理解Haskell中的并行性,我很好奇的是seq / rseqpar / rpar <之间的签名差异/ p>

seq :: a -> b -> b
par :: a -> b -> b

rseq :: a -> Eval a
rpar :: a -> Eval a

我了解rseqrpar是monadic版本,所以它们带有Eval部分。 但为什么seqpar都不是a -> a有点像严格的身份......应该存在“包含”的原因。

围绕seq似乎也有很多谜团。一些消息来源称a在评估b时评估(对WHNF)。其他消息来源称a在通话时评估。这真令人困惑!虽然可以通过实际测试来测试一些东西,但我担心我很容易误解结果。

2 个答案:

答案 0 :(得分:3)

类型a -> a的函数已经严格,即id。 Haskell是非严格的,因此调用函数的唯一原因是当您需要函数的结果时,因此当调用id y时,您需要该值。以类似的方式,当调用seq x y时,因为您需要该值。

Haskell中未指定seq的操作语义,这可能是您发现它神秘的原因。更容易理解的功能是pseqpseq函数计算其对WHNF的第一个参数,然后返回其第二个参数。 seq函数可能与pseq相同,但也可能不同。 它由其指称语义定义(Haskell报告中的6.2节):

seq ⊥ b = ⊥
seq a b = b, if a /= ⊥

由此可以得出结论,seq在两个参数中都是严格的。对于严格的函数,调用者很可能会评估参数,因为这不会产生语义差异。因此,在调用seq时,调用者可以按任何顺序评估任何参数组合。

答案 1 :(得分:0)

简而言之,seq doen 评估其论点,它只是在ab之间引入了依赖关系:只要b被评估为WHNF,a也被评估。

par以同样的方式执行此操作:每当评估b a时,可以并行评估。

这种语义是seq a a因此seq a无用的原因。此外,允许seq直接评估a会破坏纯度。