【问题标题】:Does Haskell's 'evaluate' reduce to normal or WHNF?Haskell 的“评估”是否降低到正常或 WHNF?
【发布时间】:2016-01-10 02:28:20
【问题描述】:

我了解 (I think) Haskell 的 seq 将(通常)将 reduce 作为 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 初学者)?

【问题讨论】:

  • 顺便说一句,根本没有办法多态地(没有类型类)评估 WHNF 之外的值。
  • @ReidBarton:你能再解释一下吗(或者是this)?
  • 这和那个链接里的不一样,只是没有类型类,你无法获得有关如何访问未知类型值的子部分的信息。 (嗯,无论如何都没有高级方法 - 也许有一些使用垃圾收集器数据的非常不安全的方法)
  • @ØrjanJohansen:这与x 是否相关?
  • @raxacoricofallapatorius 大概它是作为一般性陈述提出的,其中一个特化是evaluate - 接受完全多态的参数 - 不会评估超出 WHNF 的值。

标签: haskell lazy-evaluation denotational-semantics


【解决方案1】:

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

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

【讨论】:

  • 完美!我一发布就想知道这一点,但我对 IO 操作以及它们如何工作(尤其是当它们在与 GHCi 交互时“嵌入”时)仍然很模糊,我无法完全确定它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多