只是随意思考我的众多length
调用,我发现编译器可以通过不变性和引用透明度来判断任何列表的长度(即使是新的列表是concat
- 来自现有的已知列表/代码路径。然后它可能会取代所有length l
"电话"在低级代码生成期间,实际 int在某个阶段保持不变,对吧?
想知道它是否确实存在,或者我是否在初学者中缺少关于纯函数式语言/编译器的东西。
答案 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)个长度调用,但会丢失一些列表属性。