pseq可以用seq来定义吗?

时间:2017-02-11 21:18:23

标签: haskell lazy-evaluation strictness

据我所知,seq a b在返回a之前评估(强制)bb。它不能保证首先评估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 bb);因此xseq a b会在a之前评估b

xseqpseq的有效实施吗?如果没有,上述论点有什么问题(并且可以根据pseq来定义seq吗?

2 个答案:

答案 0 :(得分:0)

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

问题

xseq a b = (seq a id) b

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

答案 1 :(得分:0)

可以用pseq来定义seq吗?

在GHC中-是的。

如Alec所述,您还需要镜像烟雾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 #-}

我让美洛美来决定这是否也符合镜象烟雾...