是'长度' GHC将呼叫重写为常量整数?

时间:2016-12-04 14:14:04

标签: haskell ghc

只是随意思考我的众多length调用,我发现编译器可以通过不变性和引用透明度来判断任何列表的长度(即使是新的列表是concat - 来自现有的已知列表/代码路径。然后它可能会取代所有length l"电话"在低级代码生成期间,实际 int在某个阶段保持不变,对吧?

想知道它是否确实存在,或者我是否在初学者中缺少关于纯函数式语言/编译器的东西。

2 个答案:

答案 0 :(得分:8)

我认为问题是询问GHC是否在编译时将length [1,2,3]转换为3。 GHC 8.0.1是进行此优化的第一个GHC版本(至少在我安装的版本中)。

现在,让我们转到问题的第二部分。让我们从维基百科的GHC的第一个beta版本的日期作为GHC的开始日期:1991年4月1日.GHC 8.0.1于2016年5月发布。所以,看来你的理论认为这是在这种情况下,验证了表征25年以上编译器项目的优化。

答案 1 :(得分:2)

这一切都取决于所使用的数据结构。常规列表是简单的单链表:

data List a = Nil | Cons a (List a)

您可以想象length的定义如下:

length []     = 0
length (x:xs) = 1 + length xs

这需要O(n)时间来运行,因为没有更快的方法来确定这个结构的长度。

由于字符串位于文本文件中,因此它们在编译时不是常量,并且必须正常评估length次调用。

使用包Data.Vector可以获得O(1)个长度调用,但会丢失一些列表属性。