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
实现。例如,一个人可以实现(+)
,这样它有时只需要查看第一个元素,并且由于太懒散,因此可以在评估整个列表之前终止。