Haskell 为什么Data.List.genericLength实现为右折叠?

Haskell 为什么Data.List.genericLength实现为右折叠?,haskell,Haskell,genericLength从base 4.12开始实施,如下所示: genericLength::(Num i)=>a]>i {-#NOINLINE[1]一般长度#-} genericLength[]=0 一般长度(_:l)=1+一般长度l {-#规则 “genericLength”genericLength=(strictGenericLength::[a]->Int); “genericLength Integer”genericLength=(strictGenericLength::[a

genericLength
从base 4.12开始实施,如下所示:

genericLength::(Num i)=>a]>i
{-#NOINLINE[1]一般长度#-}
genericLength[]=0
一般长度(_:l)=1+一般长度l
{-#规则
“genericLength”genericLength=(strictGenericLength::[a]->Int);
“genericLength Integer”genericLength=(strictGenericLength::[a]->整数);
#-}
strictGenericLength::(Num i)=>[b]->i
strictGenericLength l=gl l 0
哪里
gl[]a=a
gl(xs)a=设a'=a+1在a'`seq`gl xs a'
它基本上是一个
foldr
,除了
Int
Integer
之外,它执行一个
foldl'


为什么它不在所有情况下都使用
foldl'
?foldr是否会为长列表建立大的thunk?

genericlelength
在实现时会考虑到一些问题,如Peano数字:

data Peano = Zero | Succ Peano
使用此表示法的数字可以是非严格的,因此像
genericLength[1..]>5这样的操作将返回True,而不是无法终止

对于Num的大多数其他合理实现而言,
genericLength
中的foldr确实会导致您提到的问题。

它本身并不会构建大量长列表,这取决于
Num
实现。例如,一个人可以实现
(+)
,这样它有时只需要查看第一个元素,并且由于太懒散,因此可以在评估整个列表之前终止。