Haskell 解释如何使用foldl的此特定功能
foldl是从左侧向上折叠列表。因此,首先我们得到Haskell 解释如何使用foldl的此特定功能,haskell,Haskell,foldl是从左侧向上折叠列表。因此,首先我们得到acc=0并将列表xs放到x,然后执行函数->acc+x。经过计算,我们得到新的acc,它等于acc+x。但为什么呢?我认为acc+x的这个结果是基于函数x->acc+x的x的新值。你应该看看foldl的定义: sum :: (Num a) => [a] -> a sum xs = foldl (\acc x -> acc + x) 0 xs foldl接收一个函数,该函数包含两个参数、一个值(“起始值”或累加器)
acc=0
并将列表xs放到x,然后执行函数->acc+x
。经过计算,我们得到新的acc,它等于acc+x
。但为什么呢?我认为acc+x
的这个结果是基于函数x->acc+x
的x的新值。你应该看看foldl的定义:
sum :: (Num a) => [a] -> a
sum xs = foldl (\acc x -> acc + x) 0 xs
foldl接收一个函数,该函数包含两个参数、一个值(“起始值”或累加器)和一个列表。
如果列表为空,则返回当前计算。
如果大小写不为空,则它使用与函数相同的函数递归调用,累加器是函数调用的结果,使用累加器作为第一个参数,列表的第一个元素作为第二个参数,列表的尾部用作递归调用的列表
因此,sum中使用的lambda函数变得非常清楚,它将acc作为第一个参数,将列表的元素作为第二个参数,并返回两者的和
调用以下各项的结果:
foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs
您应该看看foldl的定义:
sum :: (Num a) => [a] -> a
sum xs = foldl (\acc x -> acc + x) 0 xs
foldl接收一个函数,该函数包含两个参数、一个值(“起始值”或累加器)和一个列表。
如果列表为空,则返回当前计算。
如果大小写不为空,则它使用与函数相同的函数递归调用,累加器是函数调用的结果,使用累加器作为第一个参数,列表的第一个元素作为第二个参数,列表的尾部用作递归调用的列表
因此,sum中使用的lambda函数变得非常清楚,它将acc作为第一个参数,将列表的元素作为第二个参数,并返回两者的和
调用以下各项的结果:
foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs
从您的问题来看,听起来您不明白lambda函数
(\acc x->acc+x)
在这里是如何工作的
该功能不是x->acc+x
,而是acc x->acc+x
。事实上,你可以把“和”方程改写为
sum [1,2,3] = ((0 + 1) + 2) + 3 = 6
因为(\acc x->acc+x)
与(+)
我建议您(重新)阅读您的问题,听起来您不明白lambda函数
(\acc x->acc+x)
在这里是如何工作的
该功能不是x->acc+x
,而是acc x->acc+x
。事实上,你可以把“和”方程改写为
sum [1,2,3] = ((0 + 1) + 2) + 3 = 6
因为(\acc x->acc+x)
与(+)
我建议你(重读)让我们看看你对总和的定义
sum xs = foldl (+) 0 xs
让我们也来看看foldl的签名:
sum :: (Num a) => [a] -> a
sum xs = foldl (\acc x -> acc + x) 0 xs
嗯,好的,我们需要向foldl输入什么才能得到最末端的值(->a
)
(a->b->a)
。虽然不准确,但为了简洁起见,我们会说它是一个接受两个参数的函数(但你我都知道,它接受一个参数并返回另一个接受一个参数的函数)a
的值。请注意,我们的curried函数来自步骤1。获取a
类型的内容并返回a
类型的内容。有趣…嗯b
的列表。注意我们在步骤1中使用的curry函数,以及a
类型和b
类型的函数(\acc x->acc+x)
。这是一个匿名函数,或lambda,它接受两个参数(记住,它是用咖喱做成的),acc
和x
,并返回它们的和0
作为起始值xs
作为折叠列表sum[1,2,3]
foldl
调用我们的函数(\acc x->acc+x)
,为acc
使用0
和xs
的第一个值,1
foldl :: (a -> b -> a) -> a -> [b] -> a
这个结果不会存储在acc
或x
中,因为它们只是我们的小lambda函数中的参数foldl
将使用该值(有关具体实现,请参阅的答案)
记住,lambda函数的结果与第一个参数的类型相同吗?foldl可以使用前一个和,并将其与second元素一起传递回lambda函数
0 + 1
在对所有元素执行此操作之前:
(0 + 1) + 2
正如所指出的,如果您已经执行了以下操作,这是相同的:
((0 + 1) + 2) + 3
6
使用此函数,您可以更容易地看出,我们不仅仅是“设置”某个变量并将其添加到其中
希望这有帮助
旁注: 对于sum的定义,您不必明确说明
sum
采用xs
。您可以将其保留为:
sum=foldl(\acc x->acc+x)0
这就利用了curry,因为如果我们只提供foldl的前两个参数——像(a->b->a)
这样的curry函数和a
类型的值——我们会得到什么
[b]->a
一种函数,它接受类型为
b
的列表,并返回类型为A
的值!这就是所谓的。只是考虑一下:-(<>P>)让我们看一下你的和的定义< /P>
sum xs = foldl (+) 0 xs
让我们也来看看foldl的签名:
sum :: (Num a) => [a] -> a
sum xs = foldl (\acc x -> acc + x) 0 xs
嗯,好的,我们需要向foldl输入什么才能得到最末端的值(->a
)
(a->b->a)
。虽然不准确,但为了简洁起见,我们会说它是一个包含两个参数的函数(但你我都知道