Haskell的"评估"是否会降低到正常水平或WHNF?

oro*_*ome 8 haskell lazy-evaluation denotational-semantics

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

?> let x = (trace "foo" Foo (trace "bar" Bar 100)) in seq x 0
foo
0
Run Code Online (Sandbox Code Playgroud)

但是,虽然文档evaluate说它也减少了它对WHNF的参数,但看起来它实际上完全将其参数完全减少到正常形式:

?> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x
foo
Foo bar
(Bar 100)
Run Code Online (Sandbox Code Playgroud)

我可以确认这个(明显的)差异

?> let y = (trace "foo" Foo (trace "bar" Bar 100))
?> seq y 0
foo
0
?> :sprint y
y = <Foo> _
Run Code Online (Sandbox Code Playgroud)

和

?> let z = (trace "foo" Foo (trace "bar" Bar 100))
?> evaluate z
foo
Foo bar
(Bar 100)
?> :sprint z
z = <Foo> (<Bar> 100)
Run Code Online (Sandbox Code Playgroud)

如果文档evaluate是正确的,那么行为seq和不evaluate应该相同吗?我在这里缺少什么(作为Haskell初学者)?

Ørj*_*sen 15

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

?> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x >> return ()
foo
Run Code Online (Sandbox Code Playgroud)