"Non-lazy branch of GHC" 不懈努力的Haskell编译器部分。
"Non-lazy branch of GHC" 不懈努力的Haskell编译器部分。
我听说GHC有一个分支,可以默认编译成严格模式的代码,但可以通过注释启用惰性模式。(如我所记得的,有一个金融公司开发了这个分支,并将其用于生产代码。)这是真的吗?我找不到它。
这个人还建议,严格求值比惰性求值(默认情况下)更实用的观点越来越被接受。但我在Haskell邮件列表中没有找到这个观点的证实,但这可能是因为那里的人们不太实践导向?
我在严格的Haskell上找到的都是像$!
和rnf
这样的显式内容。虽然我认为惰性求值非常优雅,但我想在Haskell中开发一个程序,我想避免空间泄漏并希望具有可预测的性能。
免责声明:我并不是在为严格性辩护,我只想看看严格的Haskell或类似的东西。
您正在寻找Disciple。
在Haskell中要区分两种懒惰。一种是懒惰I/O,这是一种可怕的事情,可以通过iteratee库来解决(无耻的广告:包括我的pipes库)。然后还有纯计算中的懒惰,这仍然存在辩论,但我会尝试总结懒惰的关键优点,因为您已经熟悉缺点。
懒惰更高效
一个简单的例子是:
any = foldr (||) False
any
查找列表中是否有任何一个值为True
。这只计算了第一个True
之前的元素,所以无论列表有多长都不重要。
懒惰只计算它必须计算的内容,这意味着如果您连接两个惰性计算,它实际上可以改善生成计算的时间复杂度。这篇Stack Overflow评论给出了另一个很好的例子。
这实际上是iteratee库非常资源高效的原因。它们只做工作以生成结果,这导致非常高效的内存和磁盘使用以及非常易于使用的语义。
懒惰本质上更易组合
对于那些既编写过严格语言又编写过函数式语言的人们来说,这是众所周知的,但我在开发pipes
库时无意中证明了这一点的局限性,其中惰性版本是唯一允许Category
实例的版本。管道实际上可以在任何单子中工作,包括纯Identity
单子,因此我的证明也可以转换为纯代码。
这就是我相信懒惰性(延迟计算)在编程中真正成为未来的原因,然而我仍然认为是否正确实现 Haskell 的“懒惰性”仍是一个未决问题。