Haskell中的一些基本列表操作(例如ghc)是否与其命令式对应物等效地进行了优化?
例如,如果我有一些有限但在运行时列表中计算它的长度是附加到此列表还是评估函数(长度xs)必须递归遍历整个列表?
编译器是否有一些常见的Haskell(ghci或一般)优化列表?
答案 0 :(得分:8)
Haskell非常擅长对列表进行优化,但不是您描述的类型。 Haskell对列表没有“特殊”处理 - 它们就像其他普通的Haskell类型一样,虽然有一些内置的语法糖。这没什么比
更特别的了data List a = Nil | Cons a (List a)
会是。
Haskell使用所谓的foldr / build fusion来优化列表,例如,优化map f (filter p list)
以便它不会为filter
生成中间列表,但会在同一遍历中同时执行映射和过滤器。有关“融合”的详细信息,请参阅here,或有关其工作原理的详细信息,请参阅here。
此外,Haskell更现代的阵列库使用更具侵略性的融合类型,例如将sum (map f (enumFromN 0 n))
融合到从0
到n-1
的尾递归迭代,这基本上就是你想要的。调查vector package,this blog post可以进行流融合,以及this paper了解详细信息。
答案 1 :(得分:1)
不,Haskell不这样做。如果您计算以下代码:
let x = [1..5]
let y = [1..1000000]
编译器会花费更长的时间来查找y
的长度而不是x
,因为y
中有更多的值,并且编译器必须计算一次才能找到长度列表。