是否可以在 Haskell 中关闭惰性求值?
是否有特定的库编译器标志来促进这一点?
我想用我不久前编写的旧程序尝试一些新的东西,看看我是否可以提高性能。
你不能关闭惰性,因为 Haskell 的 I/O 系统依赖于它。如果没有惰性求值,该程序将运行到一个繁忙的循环中,而不会输出任何内容:
main = forever (putStrLn "Hello!")
这是因为forever c
是一个无限程序。使用惰性求值时,程序仅在运行下一条指令所需的范围内进行计算。如果关闭惰性,每个函数都变得严格,包括(>>)
,这基本上使forever
函数发散:
forever c = let cs = c >> cs in cs
但是,您可以向构造函数和模式添加严格性注释。当一个函数是严格的时,它的参数被强制作为结果评估的一部分,与是否需要参数无关。这类似于急切的评估。
除了 Daniel Wagner 列出的内容之外,您可能还想看看类似的问题Is there a Haskell compiler or preprocessor that uses strict evaluation?.
主要的建议是使用分析工具并学习如何优化 Haskell,因为大多数人会认为它是一种关闭非严格评估的不同语言。
Haskell 有一个变体,称为 pH(http://csg.csail.mit.edu/projects/languages/ph.shtml),它使用热切评估,同时仍提供非严格语义。Haskell 报告谨慎地说它是一种非严格的语言。懒惰是描述和实施非严格性的明显方式。
因此,如果您的问题是“我们能否在保持非严格语义的同时使用不同的评估系统”,您可以查看 pH。如果您的问题是“是否有一个 Haskell 版本共享表面语法但默认情况下是严格的”,我认为它已被其他答案所涵盖。
您可以在模块中启用Strict
pragma,这将导致默认情况下所有内容都是严格的。
简单回答是不。更复杂的答案是 Haskell 建立和评估函数的计算模型以惰性方式工作。正如您将在其他答案中读到的那样,有一些方法可以在正常之前强制评估某些功能,并且偶尔会这样做。但是有很大一部分有效的 Haskell 没有范式。这包括IO功能和大量的标准前奏。
结论:没有办法在 Haskell 中关闭惰性求值,然后有办法在 C 中关闭指针运算或在 Java 的 Ruby 中关闭 OO。我怀疑这比你要远得多,尽管这个问题会带你去。(没有--strict
模式),但如果你真的想看看这个兔子洞有多深, Simon Peyton Jones 的“在股票硬件上实现惰性函数式语言:无脊椎无标签 G 机器”是一次值得冒险的冒险。
该strict-identity
软件包具有严格的Identity
monad 版本。
你可以在这里找到它: https ://hackage.haskell.org/package/strict-identity
用法如下所示:
foo = runStrictIdentity $! do
x <- f a b
y <- g x y
return $! x + y
每次使用return
或 bind时>>=
,都会使用 评估这两个部分seq
,只要您的数据结构不太深,就可以合理保证严格性。这适用于数字和基本结构。