Haskell 折叠如何处理空列表?
当我们折叠包含一个或多个元素的列表时,如下所示:Haskell 折叠如何处理空列表?,haskell,fold,Haskell,Fold,当我们折叠包含一个或多个元素的列表时,如下所示: foldr (+) 0 [1,2,3] 我们得到: foldr(+)0(1:2:3:[]) foldr(+)1+(2+(3+0))//6 现在,当列表为空时: foldr (+) 0 [] 结果:foldr(+)0([]) 由于(+)是二进制运算符,它需要两个参数才能完成,但在这里我们将结束(+)0。它是如何导致0而不抛出部分应用函数的错误的。简短回答:您得到初始值z 如果给foldl或foldr一个空列表,那么它将返回初始值。工作原理如下
foldr (+) 0 [1,2,3]
我们得到:
foldr(+)0(1:2:3:[])
foldr(+)1+(2+(3+0))//6
现在,当列表为空时:
foldr (+) 0 []
结果:foldr(+)0([])
由于(+)是二进制运算符,它需要两个参数才能完成,但在这里我们将结束
(+)0
。它是如何导致0而不抛出部分应用函数的错误的。简短回答:您得到初始值z
如果给foldl
或foldr
一个空列表,那么它将返回初始值。工作原理如下:
因此,由于不存在x1
,…,xn
函数将永远不会应用,并返回z
我们还可以检查:
因此,如果我们给foldr
一个空列表,那么go
将立即处理该空列表,并返回初始值z
因此,更简洁的语法(效率稍低,如函数注释中所述)是:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
请注意,根据
f
的实现情况,可以对无限列表执行foldr
:如果在某个点f
只查看初始值,然后返回一个值,然后可以删除递归部分。简短回答:您将获得初始值z
如果给foldl
或foldr
一个空列表,那么它将返回初始值。工作原理如下:
因此,由于不存在x1
,…,xn
函数将永远不会应用,并返回z
我们还可以检查:
因此,如果我们给foldr
一个空列表,那么go
将立即处理该空列表,并返回初始值z
因此,更简洁的语法(效率稍低,如函数注释中所述)是:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
请注意,根据
f
的实现,可以在无限列表上执行foldr
:如果在某个点f
只查看初始值,然后返回一个值,则可以删除递归部分。(+0)
与foldr(+)0[]
您可以将foldr f z xs
视为用f
替换xs
中的所有:
,并将[]
替换为z
。因此foldr(+)0[]
将[]
替换为0
,并且没有:
可替换,因此+
从不使用。(+0)
与foldr(+)0[]
您可以将foldr f z xs
想象为“替换”所有:
在xs
中使用f
和[]
(如果存在)使用z
。因此foldr(+)0[]
将[]
替换为0
,并且没有要替换的:
,因此从不使用+
。
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ z [] = z
foldr f z (x:xs) = f x (foldr f z xs)