【发布时间】:2020-01-24 16:08:42
【问题描述】:
我知道seq 用于通过避免不必要的懒惰来提高性能。我只想知道名字是从哪里来的?它来自“顺序”还是“顺序”?以及名称与严格评估有何关系?
【问题讨论】:
标签: haskell
我知道seq 用于通过避免不必要的懒惰来提高性能。我只想知道名字是从哪里来的?它来自“顺序”还是“顺序”?以及名称与严格评估有何关系?
【问题讨论】:
标签: haskell
它来自sequence point。这是 C 中众所周知的概念,它确实与 Haskell 中的 seq 运算符非常相似:左侧的每个计算都应该在右侧的任何计算之前完成。
当然,Haskell seq 的要求要低一些:它只是要求在评估右侧的结果之前将左侧的事物评估为弱头范式。而且它根本不保证任何特定的评估顺序†,只是如果左边的表达式是⊥,那么右边的表达式不能被评估。
请参阅 pseq 或 deepseq 以获得更接近 C 所称的序列点的更强大的替代方案。
†实际上,C 或 C++ 序列点也不保证计算顺序,只保证任何 副作用 的顺序正确。但是,在 C 中,副作用无处不在,因此除了低级优化之外,您可以通常假设序列点顺序会得到维护,而 GHC 实际上会经常抛出 seqs它知道表达式不会发散。
【讨论】:
seq a b 的合法实现将是:“评估b,然后a,然后返回b”。
a 是⊥,那么a `seq` b 一定不能返回b 的结果。
⊥,您可以返回b 的结果。我认为说你保证b 不会在任何意义上被“评估”(或查看)是误导,甚至实际上是错误的(我认为这是与pseq 的主要区别)。我认为“强制seq a b 的结果必然会强制a 和seq a b = b 当a != ⊥”更准确。
b 的结果,如果它是 ⊥”——这在 Haskell 中至少可以说是有道理的,而无需提及任何实现。只是,你不能实际上这样做,一般来说——因为它需要首先证明b是⊥,为此你需要解决这个问题停止问题。
seq a b = b when a != ⊥”,然后描述它在 GHC 中的实际工作方式,我会说“强制seq a b 的结果必然会强制a”。