Haskell 的 'evaluate' 是正常还是 WHNF?

Does Haskell's 'evaluate' reduce to normal or WHNF?

我理解() that Haskell's seq, will (generally) reduce its first argument to 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 的文档是正确的,那么 seqevaluate 的行为不应该相同吗?我在这里错过了什么(作为 Haskell 初学者)?

你缺少的是 GHCi 还 打印 IO 操作的结果(如果它们可以显示并且不是 ()),does 使其计算为正常形式。请尝试:

λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x >> return ()
foo