【问题标题】:Haskell: seq, par, rseq, rpar signaturesHaskell:seq、par、rseq、rpar 签名
【发布时间】:2017-03-09 21:53:26
【问题描述】:

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

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

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

我知道rseqrpar 是一元版本,所以它们带有Eval 部分。 但是为什么seqpar 不都只是a -> a 有点像严格的身份......应该存在“复杂化”的原因。

seq 周围似乎也有很多谜团。一些消息来源说 a 在评估 b 时评估(到 WHNF)。其他消息来源说a 在通话时进行评估。真的很混乱!虽然可以通过实际测试来试驾一些东西,但恐怕我很容易误解结果。

【问题讨论】:

  • 请参阅 this 了解有关 seq 的信息以及为什么它是 2 参数函数。

标签: haskell


【解决方案1】:

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

seq 的操作语义在 Haskell 中没有指定,这可能就是你觉得它神秘的原因。更容易理解的功能是pseqpseq 函数将其第一个参数计算为 WHNF,然后返回其第二个参数。 seq 函数的作用可能与 pseq 相同,但也可能不一样。 它是由其指称语义定义的(Haskell 报告中的第 6.2 节):

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

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

【讨论】:

    【解决方案2】:

    简而言之,seq 确实 评估它的论点,它只是在 ab 之间引入依赖关系:每当 b 被评估为 WHNF 时,a也被评估。

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

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

    【讨论】:

    • 您能否详细说明为什么对 thunk 的评估会破坏纯度?我相信 thunk 和 values 是可以互换的,区别仅在于操作语义。这并不能解释为什么 rparrseq 的制作方式不同。
    • rseqrpar 在它们返回的 Eval 值的评估和它们的参数的评估之间创建依赖关系。这在Eval 的上下文中有效,因为(>>=) for Eval 在将值传递给第二个参数之前强制评估其第一个参数。
    猜你喜欢
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多