Haskell 哈斯克尔';s';评估';降低到正常或WHNF?

Haskell 哈斯克尔';s';评估';降低到正常或WHNF?,haskell,lazy-evaluation,denotational-semantics,Haskell,Lazy Evaluation,Denotational Semantics,我理解()Haskell的seq,将(通常)作为其第一个参数,并在GHCi中看到预期的这种行为: λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in seq x 0 foo 0 然而,虽然说它也将其论点简化为WHNF,但看起来它实际上将其论点完全简化为正常形式: λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x foo Foo bar (Bar 1

我理解()Haskell的
seq
,将(通常)作为其第一个参数,并在GHCi中看到预期的这种行为:

λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in seq x 0
foo
0
然而,虽然说它也将其论点简化为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> _
λ>设y=(跟踪“foo”foo(跟踪“bar”bar 100))
λ> 序号y 0
福
0
λ> :冲刺
y=_

λ>设z=(跟踪“foo”foo(跟踪“bar”bar 100))
λ> 评估z
福
富吧
(100巴)
λ> :冲刺z
z=(100)

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

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

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

顺便说一句,对于WHNF之外的值,没有任何多态性(没有类型类)计算方法。@ReidBarton:你能进一步解释一下吗(或者是吗)?这与链接中的不同,只是没有类型类,你无法获得关于如何访问未知类型值的子部分的信息。(嗯,无论如何,没有高层次的方法-也许有一些可怕的不安全的方法使用垃圾收集器的数据)@rjanJohansen:这与
x
有关吗,例如?@raxacoricocfallapatorius可能是作为一个一般性陈述提出来的,它的一个特化是
求值
——它接受一个完全多态的参数——求值不超过WHNF.Perfect!我一发帖就想知道这一点,但我对IO操作及其工作方式(特别是当它们“嵌入”在与GHCi的交互中时)仍然不够清楚,我无法完全确定。
λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x >> return ()
foo