19

是否可以在 Haskell 中关闭惰性求值?

是否有特定的库编译器标志来促进这一点?

我想用我不久前编写的旧程序尝试一些新的东西,看看我是否可以提高性能。

4

7 回答 7

36

有很多方法可以让懒惰的事情变得严格。你可以:

  1. 显式插入虚假模式匹配。
  2. 使用seq或其近亲($!)
  3. 使用BangPatterns.
  4. 在您的类型上使用严格性注释。

更多信息在这里

于 2013-03-26T01:55:07.667 回答
17

你不能关闭惰性,因为 Haskell 的 I/O 系统依赖于它。如果没有惰性求值,该程序将运行到一个繁忙的循环中,而不会输出任何内容:

main = forever (putStrLn "Hello!")

这是因为forever c是一个无限程序。使用惰性求值时,程序仅在运行下一条指令所需的范围内进行计算。如果关闭惰性,每个函数都变得严格,包括(>>),这基本上使forever函数发散:

forever c = let cs = c >> cs in cs

但是,您可以向构造函数和模式添加严格性注释。当一个函数是严格的时,它的参数被强制作为结果评估的一部分,与是否需要参数无关。这类似于急切的评估。

于 2013-03-26T01:59:28.650 回答
11

除了 Daniel Wagner 列出的内容之外,您可能还想看看类似的问题Is there a Haskell compiler or preprocessor that uses strict evaluation?.

  • 答案包括 DDC 编译器,它试图制作一个严格版本的 haskell,并且只显式地惰性化
  • monad.reader 12中描述的ghc 插件
  • “到处使用 nfdata 和 rnf” - solrize
  • 和更多

主要的建议是使用分析工具并学习如何优化 Haskell,因为大多数人会认为它是一种关闭非严格评估的不同语言。

于 2013-03-26T02:04:23.373 回答
6

Haskell 有一个变体,称为 pH(http://csg.csail.mit.edu/projects/languages/ph.shtml),它使用热切评估,同时仍提供非严格语义。Haskell 报告谨慎地说它是一种非严格的语言。懒惰是描述和实施非严格性的明显方式。

因此,如果您的问题是“我们能否在保持非严格语义的同时使用不同的评估系统”,您可以查看 pH。如果您的问题是“是否有一个 Haskell 版本共享表面语法但默认情况下是严格的”,我认为它已被其他答案所涵盖。

于 2013-03-27T02:45:41.500 回答
5

您可以在模块中启用Strictpragma,这将导致默认情况下所有内容都是严格的。

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

于 2016-09-07T16:57:49.927 回答
3

简单回答是不。更复杂的答案是 Haskell 建立和评估函数的计算模型以惰性方式工作。正如您将在其他答案中读到的那样,有一些方法可以在正常之前强制评估某些功能,并且偶尔会这样做。但是有很大一部分有效的 Haskell 没有范式。这包括IO功能和大量的标准前奏。

结论:没有办法在 Haskell 中关闭惰性求值,然后有办法在 C 中关闭指针运算或在 Java 的 Ruby 中关闭 OO。我怀疑这比你要远得多,尽管这个问题会带你去。(没有--strict模式),但如果你真的想看看这个兔子洞有多深, Simon Peyton Jones 的“在股票硬件上实现惰性函数式语言:无脊椎无标签 G 机器”是一次值得冒险的冒险。

于 2013-03-26T06:35:42.427 回答
2

strict-identity软件包具有严格的Identitymonad 版本。

你可以在这里找到它: https ://hackage.haskell.org/package/strict-identity

用法如下所示:

foo = runStrictIdentity $! do
    x <- f a b
    y <- g x y
    return $! x + y

每次使用return或 bind时>>=,都会使用 评估这两个部分seq,只要您的数据结构不太深,就可以合理保证严格性。这适用于数字和基本结构。

于 2014-02-08T08:39:32.823 回答