关于haskell:GHC的非懒惰分支

Non-lazy branch of GHC

我听说GHC的一个分支默认编译为严格的代码,而惰性可以通过注释来启用。(IIRC,他说是一家金融公司开发了分支机构,并将其用于生产代码。)是这样吗?我找不到。

该人士还建议,严格评估比懒惰评估(默认情况下)更实际的观点越来越得到认可。我在haskell邮件列表中没有发现这一点,但这可能是因为那里的人没有以实践为导向?

我在严格的haskell上发现的都是明确的东西,比如$!rnf。虽然我觉得懒惰的评估非常优雅,但我想在Haskell开发一个程序,在那里我想避免空间泄漏,并希望有可预测的性能。

免责声明:我不是在为严格辩护,我只是想看看严格的哈斯克尔或类似的东西。


你在找弟子。

所以哈斯凯尔有两种懒惰可以区分。有懒惰的I/O,这是一个可憎的问题,由迭代库(无耻的插件:包括我的管道库)解决。那么纯计算中存在着惰性,这仍然是一个有待讨论的问题,但是我将尝试总结一下惰性的主要优点,因为您已经熟悉了这种缺点:

懒惰更有效

一个简单的例子是:

1
any = foldr (||) False

any查找列表中的任何值是否为True。这只对第一个True之前的元素进行评估,因此列表是否很长并不重要。

懒惰只计算尽可能多的东西,这意味着如果将两个懒惰的计算链接在一起,它实际上可以提高结果计算的时间复杂性。这个堆栈溢出注释给出了另一个很好的例子。

这就是为什么迭代器库具有很高的资源效率的原因。它们只需要做尽可能多的工作来生成结果,这将导致非常高效的内存和磁盘使用,并且具有非常易于使用的语义。

懒惰从本质上来说更为沉着。

这是众所周知的人谁都用严格和功能性语言编程,但实际上我无意中证明了这一点有限的同时,在工作的pipes库,其中懒惰的版本是唯一允许Category实例的版本。实际上,管道可以在任何Monad中使用,包括纯IdentityMonad,所以我的证明也可以翻译为纯代码。

这就是为什么我相信懒惰实际上是编程的未来的真正原因,但是我仍然认为这是一个关于Haskell是否实现了懒惰"正确"的开放性问题。


听起来你好像听说过罗伯特·埃纳尔斯博士关于GHC的推测性评估的论文。他创建了一个称为"规格评估"叉的GHC叉,在那里进行了投机评估。因为haskell是非严格的,而不是显式的懒惰,所以spec-eval严格到了它真正起作用的程度。虽然它在所有情况下都更快,但它需要对GHC进行较大的更改,而且从未合并。

这个问题以前在这个网站上得到过解答。


I have heard there is a branch of GHC that compiles to strict code by default whereas laziness can be enabled by annotation

您可以尝试ghc 8.0.2、8.2.2或8.4.1,也就是最近三个版本中的任何一个。它们有一个用于数字代码等的{-# LANGUAGE Strict #-}杂注。

financial company develops the branch and uses it for production code.) Is that true? I can't find it.

渣打银行确实开发了自己的haskell编译器。我不希望他们把它提供给公众。我不确定默认情况下是否严格。

The person also suggested that the opinion that strict evaluation is more practical than lazy evaluation

这既没有意义,也没有证据支持。实际上,llvm hs pure包通过选择使用状态monad的严格版本而不是惰性版本引入了一个bug。此外,类似并行IO包的东西将无法工作。

I'd like to develop a a program in Haskell where I want to avoid space leaks and would like to have predictable performance.

在过去的两年里,我没有被懒惰造成的空间泄漏所咬。我建议您使用基准测试和分析应用程序。用可预测的性能编写haskell要比添加严格的注释和希望程序仍能编译容易得多。通过理解程序、分析和学习功能数据结构,您将得到更好的服务,而不是不加注意地添加编译器语用以提高程序的性能。


关于为什么你不应该回避哈斯克尔的懒惰,有人说过一些好的话,但我觉得最初的问题仍然没有答案。

Function application in Haskell is non-strict; that is, a function argument is evaluated only when required.

~haskell report 2010>预定义类型和类严格评估

不过,这有点误导人。实现可以在需要函数参数之前对其进行评估,但只能在有限的范围内进行。您必须保留非严格的语义:因此,如果参数的表达式产生无限循环,而不使用该参数,则使用该参数的函数调用不能是无限循环。

因此,允许您以一种不是完全"懒惰"的方式实现haskell,但它也不能是"严格"的。乍一看这似乎是矛盾,但事实并非如此。您可能需要查看的几个相关主题:

  • EAGER Haskell,默认情况下使用EAGER评估的Haskell编程语言的一种实现。我相信这就是你所想的(尽管它不是GHC的一个分支)。
  • 投机执行和投机并行(参见投机包)。
  • 《乐观评价》是SPJ关于用严格的优化方法加快温室气体排放速度的一篇论文。

如果我理解正确的话,严格的haskell就不能像我们所知道的那样拥有一元I/O。haskell的思想是,所有haskell代码都是纯的(包括IO操作,其工作方式与状态monad类似),而"main"为运行时提供了一个IO()类型的值,然后运行时会反复强制排序运算符>>=。

为了与泰克莫的文章形成对比,你可以看看罗伯特·哈珀的博客,*http://existentialtype.wordpress.com/2011/04/24/the-real-point-of-laziness/及相关。它是双向的。

根据我的经验,一开始懒惰是很困难的,但后来你习惯了,这很好。

休斯的论文《为什么函数式编程很重要》是一篇经典的关于懒惰的文章,你应该可以很容易地找到它。