【发布时间】:2017-02-11 21:18:23
【问题描述】:
据我所知,seq a b 在返回 b 之前评估(强制)a 和 b。它不保证首先评估a。
pseq a b 首先评估a,然后评估/返回b。
现在考虑以下几点:
xseq a b = (seq a id) b
函数应用需要先对左操作数求值(得到一个 lambda 形式),在进入函数之前不能盲目求右操作数,因为这会违反 Haskell 的非严格语义。
因此(seq a id) b 必须首先评估seq a id,这会强制a 和id(以某种未指定的顺序(但评估id 什么都不做)),然后返回id b(即b );因此xseq a b 在b 之前评估a。
xseq 是pseq 的有效实现吗?如果不是,上述论点有什么问题(是否可以根据seq 定义pseq)?
【问题讨论】:
-
你正在寻找的魔法真的在
lazy。 -
@melpomene 抱歉,我的意思是
seq a (\x->x) b可以变成seq a ((\x->x) b)- 一般来说,如果y在 WHNF 中,seq a y o可以变成seq a (y o)。编译器是否会执行这样的优化,我不知道,但它肯定可以。我相信就“原始操作语义”(即假装编译器根本不会更改您的代码)而言,您的函数是正确的——它只是在存在优化的情况下崩溃了。 (实际上,lazy在外延上等于id- 所以你的xseq在外延上等于pseq,并且两者都等于seq,只是在操作上没有) -
您似乎认为
f x必须首先将f评估为WHNF,但事实可能并非如此。如果严格性分析器证明f严格,我认为运行时可以首先将x评估为WHNF,而无需更改语义。我不确定这是否真的发生在 GHC 优化器中。 -
我看到到目前为止有五个人对这个问题投了反对票。我很想知道为什么。
标签: haskell lazy-evaluation strictness