【发布时间】:2016-01-10 02:28:20
【问题描述】:
我了解 (I think) Haskell 的 seq 将(通常)将 reduce 作为 WHNF 的第一个参数,并在 GHCi 中看到这种行为:
λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in seq x 0
foo
0
然而,尽管documentation for evaluate 说它也将它的参数简化为 WHNF,但看起来它实际上完全将它的参数简化为正常形式:
λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x
foo
Foo bar
(Bar 100)
我可以确认这个(明显的)差异与
λ> let y = (trace "foo" Foo (trace "bar" Bar 100))
λ> seq y 0
foo
0
λ> :sprint y
y = <Foo> _
和
λ> let z = (trace "foo" Foo (trace "bar" Bar 100))
λ> evaluate z
foo
Foo bar
(Bar 100)
λ> :sprint z
z = <Foo> (<Bar> 100)
如果evaluate 的文档是正确的,那么seq 和evaluate 的行为不应该相同吗?我在这里缺少什么(作为 Haskell 初学者)?
【问题讨论】:
-
顺便说一句,根本没有办法多态地(没有类型类)评估 WHNF 之外的值。
-
@ReidBarton:你能再解释一下吗(或者是this)?
-
这和那个链接里的不一样,只是没有类型类,你无法获得有关如何访问未知类型值的子部分的信息。 (嗯,无论如何都没有高级方法 - 也许有一些使用垃圾收集器数据的非常不安全的方法)
-
@ØrjanJohansen:这与
x是否相关? -
@raxacoricofallapatorius 大概它是作为一般性陈述提出的,其中一个特化是
evaluate- 接受完全多态的参数 - 不会评估超出 WHNF 的值。
标签: haskell lazy-evaluation denotational-semantics