8

我理解(我认为)Haskell'sseq将(通常)其第一个参数减少为WHNF,并在 GHCi 中看到这种行为:

λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in seq x 0
foo
0

然而,尽管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 初学者)?

4

1 回答 1

15

您缺少的是 GHCi 还打印IO 操作的结果(如果它们可以显示并且不是()),这确实会导致它评估为正常形式。请尝试:

λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x >> return ()
foo
于 2015-10-12T15:01:39.197 回答