【问题标题】:Shared value gets (unnecessarily) evaluated multiple times in Haskell共享值在 Haskell 中被(不必要地)多次评估
【发布时间】:2012-02-16 01:36:15
【问题描述】:

我读了this 的答案,这听起来像是在评估共享值时,它只评估一次,然后存储结果。例如:

x = 2 + 2
y = 2 + x
z = 3 + x

这里,x 被评估一次,然后存储为4,并且再也不会被评估?至少这是我的假设。我的代码有一个值,每次被引用时都会重新计算。这是一个纯粹的价值。什么时候会发生这种情况,如何强制 Haskell 在计算后记住该值?

例子:

x = [1, 1, 2]
count = fst $ getCounts x

这里,count 每次被引用时都会被评估。

【问题讨论】:

  • 您是否在进行优化编译?如果是这样,并且仍然看到这种行为,那么您可能在没有真正理解的情况下关闭了单态限制。
  • 你怎么知道它是?虽然 Haskell 编译器可以随心所欲地进行优化,并且当它可以显示计算很便宜时,GHC 可能会重复工作,但我怀疑这种情况会发生在具有这样的顶级绑定的情况下,除非 getCounts 确实非常简单。
  • ehird:我正在使用 trace 进行测试。另外,当一段简单的代码需要 5 分钟时,你会弄清楚:P

标签: haskell


【解决方案1】:

正如 Daniel Wagner 指出的那样,这里最可能的情况是 count 没有给出明确的类型签名,但您已经关闭了单态限制(例如,使用 NoMonomorphismRestriction 语言扩展)。这意味着count 的类型类似于

count :: (Num a) => a

这意味着 GHC 将 count 视为一个函数(具体而言,从任何类型 aNum 类型类字典到 a),因此结果不共享,这意味着它的值是每次使用都会重新计算。

最好的解决方案是给 count 一个明确的类型签名,例如

count :: Int

您可能也应该对x 执行相同的操作(就此而言,您的程序中的所有其他顶级定义)。

【讨论】:

  • 哇,我的脑子被炸了。不,我不明白 NoMonomorphismRestriction,是的,我使用的是 alias ghci=ghci -XNoMonomorphismRestriction。现在没了。
  • 不,我不写自己的类型签名。是时候开始了。
  • @VladtheImpala Haskell 的一般风格指南是您应该为所有顶级绑定编写类型签名。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
  • 1970-01-01
  • 2011-11-28
  • 2017-10-23
相关资源
最近更新 更多