关闭haskell中的懒惰评估

pyC*_*hon 18 haskell

是否有可能在Haskell中关闭延迟评估?

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

我想尝试一些我曾经写过的旧程序的新东西,看看我是否可以提高性能.

Dan*_*ner 36

有很多方法可以严格控制懒惰的东西.您可以:

  1. 明确插入虚假模式匹配.
  2. 使用seq或其近亲($!).
  3. 使用BangPatterns.
  4. 对类型使用严格注释.

更多信息在这里.

  • @NikitaVolkov例如,对于列表,将`foo`替换为`case xs of [] - > foo; _:_ - > foo`. (5认同)
  • 什么是虚假模式匹配? (4认同)
  • 使用`seq`或`$!`不会强制整个表达式被完全评估 - 它只强制"头部正常形式".例如,在列表计算中使用`seq`,它会急切地评估结果列表 - 但这只是"cons"保存列表的head项目.头部成员和整个尾部列表可能尚未进行评估.要强制完整计算完整的表达式,一个选项是`deepseq`,这意味着你需要实例化`NFData`类型类.另一种是针对结果类型定制的严格强制函数. (3认同)

ert*_*tes 17

你无法关闭懒惰,因为Haskell的I/O系统依赖于它.没有懒惰的评估,这个程序会在没有输出任何内容的情况下进入繁忙的循环:

main = forever (putStrLn "Hello!")
Run Code Online (Sandbox Code Playgroud)

这是因为forever c是一个无限的程序.通过延迟评估,仅在运行下一条指令时计算程序.如果你关闭懒惰,每个功能都变得严格,包括(>>),这基本上使forever功能发散:

forever c = let cs = c >> cs in cs
Run Code Online (Sandbox Code Playgroud)

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

  • 这并不能证明你无法关闭懒惰 - 它只能证明你可以关闭懒惰但仍然让它们工作的程序集受到很大限制.`forever`仅仅是一个特别明显的问题函数 - 有许多不太明显的错误会导致类似的问题 - 但足够迷恋的人可能能够识别并工作与一个Haskell子集仍然禁用懒惰的作品.+1无论如何 - 这仍然是一个好点. (6认同)
  • 你可以永远定义为"永远c = c >> =\_ - >永远c`,即使有严格的评估也能工作. (3认同)

Dav*_*rak 11

除了Daniel Wagner列出的内容之外,您可能还想看一个类似的问题是否有使用严格评估的Haskell编译器或预处理器?.

  • 答案包括DDC编译器,它试图制作严格版本的haskell并且只是显式延迟
  • monad.reader 12中描述的ghc插件
  • "使用nfdata和rnf无处不在" - solrize
  • 和更多

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


Har*_*ari 6

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

因此,如果您的问题是"我们可以使用不同的评估系统,同时保持非严格的语义",那么您可以查看pH值.如果您的问题是"Haskell的版本是否共享表面语法但默认情况下是严格的",我认为它已被其他答案所覆盖.


joe*_*elw 5

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

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