是否可以在Haskell中关闭延迟评估?
是否有特定的库编译器标志来促进这一点?
我想尝试一些我之前写过的旧程序的新功能,看看我是否可以提高性能。
答案 0 :(得分:36)
有很多方法可以严格控制懒惰事物。你可以:
seq
或其近亲($!)
。BangPatterns
。更多信息here。
答案 1 :(得分:17)
你无法关闭懒惰,因为Haskell的I / O系统依赖于它。如果没有懒惰的评估,这个程序将会在没有输出任何内容的情况下进入繁忙的循环:
main = forever (putStrLn "Hello!")
这是因为forever c
是一个无限的程序。通过延迟评估,仅在运行下一条指令时计算程序。如果你关闭懒惰,每个函数都会变得严格,包括(>>)
,这基本上会导致forever
函数出现分歧:
forever c = let cs = c >> cs in cs
但是,您可以为构造函数和模式添加严格注释。当函数是严格的时,它的参数被强制作为结果评估的一部分,而与是否需要参数无关。这类似于热切的评价。
答案 2 :(得分:11)
除了Daniel Wagner列出的内容之外,您可能还想看看类似的问题Is there a Haskell compiler or preprocessor that uses strict evaluation?。
主要的建议是使用分析工具并学习如何优化Haskell,因为大多数人认为它是一种不同的语言,关闭了非严格的评估。
答案 3 :(得分:6)
Haskell的变种称为pH(http://csg.csail.mit.edu/projects/languages/ph.shtml) 它使用急切的评估,同时仍然提供非严格的语义。 Haskell报告谨慎地说它是一种非严格的语言。懒惰是描述并且显然是实施非严格性的明显方式。
因此,如果您的问题是“我们可以使用不同的评估系统,同时保持非严格的语义”,那么您可以查看pH值。如果您的问题是“是否有一个Haskell的版本共享表面语法但默认是严格的”,我认为它已被其他答案所涵盖。
答案 4 :(得分:4)
您可以在模块中启用Strict
pragma,这将导致默认情况下所有内容都是严格的。
答案 5 :(得分:3)
简单的答案是否定的。更复杂的答案是Haskell构建和评估函数的计算模型以惰性方式工作。正如您将在其他答案中读到的那样,有些方法可以在早期正常情况下强制评估某些功能,并且偶尔会这样做。但是有很大一部分有效的Haskell没有正常形式。这包括IO功能和大量标准前奏。
结论:在Haskell中没有更多的方法来转换惰性求值,然后有一种方法可以在C中关闭指针算法或在Ruby的Java中关闭OO。我怀疑这比你更远,但这个问题会带你走。 (没有--strict
模式),但是如果你真的想看看rabit洞的深度,Simon Peyton Jones的“Implementing Lazy Functional Languages on Stock Hardware: The Spineless Tagless G-machine”是一个值得拥有的冒险。
答案 6 :(得分:2)
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
或绑定>>=
时,使用seq
评估这两部分,如果您的数据结构不太深,则可以合理保证严格性。这适用于数字和基本结构。