19

我正在寻找一个默认使用严格评估而不是惰性评估的 Haskell 编译器。我只会使用 OCaml,但 Haskell 的语法比 OCaml 的要好得多(而且 Haskell 是纯粹的,并且具有很酷的特性,例如类型类)。

我真的宁愿不要在我的程序中不断地放!s 和s 。$!带有开关或预处理器以放入严格性注释的编译器会非常好。如果在某些地方也有一种使用惰性评估的方法,那也会很有帮助,以防万一我想要一个无限列表之类的东西(我可能永远不会)。

请不要试图说服我懒惰的评估更好,我真的需要性能。IIRC,Simon Peyton Jones 甚至说惰性评估并不是真正必要的,它主要是为了防止他们使语言变得不纯。

4

11 回答 11

17

我真的不想在我的程序中不断地放 !s 和 $!s

你做错了,如果这就是你编程 Haskell 的方式:) 你根本不需要这样做。使用 GHC,使用 -O2,在适当的时候使用严格的数据类型,在适当的时候使用惰性数据类型。不要认为懒惰会成为一个问题——它可以解决很多问题。

于 2009-06-15T18:26:40.807 回答
16

如果你有一个使用严格评估的 Haskell 编译器,它不会编译 Haskell。懒惰非严格性是 Haskell 规范的一部分!

但是,还有其他选择。

  • DDC试图创建一个明确的 Haskell 惰性变体,它支持破坏性更新等内容,同时保留 Haskell 的所有其他优点。有一个问题:编译器目前只处于 α 阶段,尽管它看起来至少是可用的。

  • 像其他人一样创建一个预处理器。

  • 学习以“正确的方式”使用 Haskell。如果您可以将您的测试用例简化为可公开展示的内容,您可以将其发布在Haskell-Café 邮件列表中,人们对这些关于非严格性影响的问题非常有帮助。

于 2009-06-16T02:02:46.677 回答
12

过去曾有过两次严格评估 Haskell 的尝试:

但两者都专注于坚持 Haskell 的非严格语义,但使用最严格的评估策略,而不是真正改变语义,而且都没有真正看到曙光。

编辑:Martijn 对 strict-plugin 的建议看起来非常适合您的目的,因为它实际上可以满足您的需求,而且作者仍然活跃在 Haskell 社区中,我已经忘记了。

于 2009-06-15T13:27:19.483 回答
8

另请参阅ghc-strict-plugin ,这是GHC 插件框架的示例,在Monad Reader 12中进行了描述。

于 2009-06-15T14:03:07.853 回答
7

我感觉到你的痛苦。我日常编程中最大的 PITA 是处理那些 !@#$%^&( 空间泄漏。

但是,如果它有帮助,随着时间的推移,您确实会(艰难地)学习如何处理这个问题,并且它确实会变得更好。但我仍在等待 Andy Gill 拿出他神奇的空间泄漏分析器来解决我的所有问题。(我在上一届 ICFP 上对我发表了他的随口评论,说他想出了这个很酷的想法作为实现它的承诺。)

我不会试图说服你懒惰的评估是世界上最好的事情,但它有一些好处。我有一些流处理程序,它们通过各种组合器在仅使用 3.5 MB 左右的内存(其中超过 2MB 是 GHC 运行时)上愉快地运行在千兆字节数据上的各种组合器中搜索惰性列表。去年有人向我指出比我更聪明的人,作为一个典型的 Haskell 程序员,你真的会非常惊讶,你多么依赖惰性求值。

但是我们真正需要的是一本关于现实世界中处理惰性评估的非常好的书(这与学术界并没有太大的不同,真的,除了他们根本没有发表论文,而且我们有客户追随我们用刀),它将正确涵盖与此相关的大多数问题,更重要的是,让我们直观地了解什么会爆炸我们的堆,什么不会。

我不认为这是新事物。我确信其他语言和架构也经历过这种情况。毕竟,第一批程序员是如何处理硬件堆栈的呢?不太好,我敢打赌。

于 2009-06-15T18:37:21.193 回答
5

我认为 Jan-Willem Maessan 的pH 编译器很严格。下一个最接近的是 Robert Ennal 对 ghc 5 的推测评估分支。 spec_eval 分支并不严格,而是乐观地评估。我不知道其中任何一个是否仍然是当前/可用/等。

于 2009-06-15T13:29:42.783 回答
5

到处使用 nfdata 和 rnf 并不是一个解决方案,因为这意味着重复遍历已经评估过的大型结构。

Ben Lippmeier 博士论文(关于 DDC)的介绍性章节是关于我所见过的对 Haskell 的最佳评论——它讨论了懒惰、破坏性更新、monad 转换器等问题。DDC 有懒惰,但你必须明确提出要求,它被认为是一种效果,由DDC的类型和效果系统跟踪和管理。

于 2010-06-28T19:23:35.163 回答
5

我最近看到了这方面的一些工作:

https://ghc.haskell.org/trac/ghc/wiki/StrictPragma

您可以在此处的 SPJ 的 GHC 状态更新中听到一些关于它的信息:

http://youtu.be/Ex79K4lvJno?t=9m33s (链接开始于 9:33 的相关部分)

于 2015-02-07T15:05:29.517 回答
1

我正在寻找一个默认使用严格评估而不是惰性评估的 Haskell 编译器。

这样的编译器不会是 Haskell 编译器。如果你真的想要,你可以考虑{-# LANGUAGE Strict #-}在你的文件中放入 pragma。这将适用于 GHC 8.0.2、8.2.2 和 8.4.1,也就是编译器的最后三个版本。

如果在某些地方也有一种使用惰性评估的方法,那也会很有帮助,以防万一我想要一个无限列表之类的东西

没有这样的方法。相反,按原意使用 GHC - 作为一种惰性语言。学会正确地思考你的代码、配置文件和使用函数式数据结构将比在任何地方盲目地应用严格性编译指示有用得多。GHC 已经有一个严格分析器。

(我可能永远不会)。

这正是 llvm-hs 的作者在选择使用严格的状态单子而不是惰性单子时的想法。相反,它导致了一个意想不到的错误。懒惰和递归齐头并进。

请不要试图说服我懒惰的评估更好,我真的需要性能。

我怀疑这实际上是您想要的,因为它不能可靠地提高 Haskell 代码的性能,同时破坏现有代码并使现有资源无用。如果你打算用这种方式编写程序,请使用 OCaml 或 Scala 并离开 Haskell 社区。

IIRC,Simon Peyton Jones 甚至说惰性评估并不是真正必要的,它主要是为了防止他们使语言变得不纯。

那不是真的。您可以在此处阅读有关 Haskell 实际历史的更多信息

于 2018-04-09T01:55:40.963 回答
0

您显然已经决定严格评估的价值,但我认为您错过了使用 Haskell 的重点。Haskell 的惰性求值允许编译器/解释器采用更灵活的优化策略。强制您自己的严格性会覆盖优化器。最后,使用过度严格的评估永远不会像自动优化那样有效。尝试在 GHCI 中对一系列数字进行折叠求和,使用和不使用惰性求值。您可以很清楚地看到差异——在这种情况下,惰性求值总是更快。

于 2011-06-18T12:37:05.443 回答
0

还有seqaid,它针对的是惰性严格范围的中间。

Seqaid 是一个 GHC 插件,提供 Haskell 项目的非侵入式自动检测,用于动态严格性(和并行性)控制。这将很快包括使用最小严格性对自动空间泄漏缓解进行优化。

于 2015-10-22T00:47:18.020 回答