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
的文档是正确的,那么 seq
和 evaluate
的行为不应该相同吗?我在这里错过了什么(作为 Haskell 初学者)?
你缺少的是 GHCi 还 打印 IO 操作的结果(如果它们可以显示并且不是 ()
),does 使其计算为正常形式。请尝试:
λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x >> return ()
foo
我理解(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
的文档是正确的,那么 seq
和 evaluate
的行为不应该相同吗?我在这里错过了什么(作为 Haskell 初学者)?
你缺少的是 GHCi 还 打印 IO 操作的结果(如果它们可以显示并且不是 ()
),does 使其计算为正常形式。请尝试:
λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x >> return ()
foo