1

据我所知,seq a b评估 (forces)ab返回之前b。它不保证a首先评估。

pseq a b首先评估a,然后评估/返回b

现在考虑以下几点:

xseq a b = (seq a id) b

函数应用程序需要先对左操作数求值(得到一个 lambda 形式),并且在进入函数之前不能盲目地求右操作数,因为这会违反 Haskell 的非严格语义。

因此(seq a id) b必须首先评估seq a id,它强制aid(以某种未指定的顺序(但评估id什么都不做)),然后返回id b(即b);因此在 之前xseq a b进行评估。ab

xseq有效的实现pseq吗?如果不是,那么上述论点有什么问题(并且是否可以完全定义pseqseq

4

2 回答 2

2

答案似乎是“不,至少不是没有额外的魔法”。

问题与

xseq a b = (seq a id) b

是编译器可以看到seq a idis的结果id,这在任何地方都是严格的。如果函数是严格的,则允许函数应用程序首先评估参数,因为这样做不会改变表达式的语义。因此,优化编译器可以首先开始评估b,因为它知道最终会需要它。

于 2019-01-24T22:39:59.417 回答
0

可以pseq定义为seq?

在 GHC - 是的。

正如 Alec 所说,您还需要 mirror-smoke lazy

 -- for GHC 8.6.5
import Prelude(seq)
import GHC.Base(lazy)

infixr 0 `pseq`
pseq :: a -> b -> b
pseq x y = x `seq` lazy y

与 GHC 来源中对应的定义相匹配;进口是非常不同的。

对于其他 Haskell 实现,这可能有效:

import Prelude(seq)

infixr 0 `pseq`
pseq :: a -> b -> b
pseq x y = x `seq` (case x of _ -> y)

可能与 - 至少 - 相当于:

 -- for GHC 8.6.5
{-# NOINLINE pseq #-}

我会让 melpomene 决定这是否也符合镜面烟雾的条件......

于 2020-08-27T03:17:19.123 回答