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)