Haskell 不清楚foldl类型定义

Haskell 不清楚foldl类型定义,haskell,Haskell,我不太明白为什么(a->b->a)返回a,同时(a->b->a->[b]->a返回a。我想应该是这样的:(a->b->c)->a->[b]->c。有人能根据下面的例子向我解释一下吗。谢谢 foldl :: (a -> b -> a) -> a -> [b] -> a foldl step zero (x:xs) = foldl step (step zero x) xs foldl _ zero [] = zero 折叠功能的返回类型(类型(a->b

我不太明白为什么(a->b->a)返回a,同时(a->b->a->[b]->a返回a。我想应该是这样的:(a->b->c)->a->[b]->c。有人能根据下面的例子向我解释一下吗。谢谢

foldl :: (a -> b -> a) -> a -> [b] -> a
foldl step zero (x:xs) = foldl step (step zero x) xs
foldl _    zero []     = zero

折叠功能的返回类型(类型
(a->b->a)
)必须与其第一次输入的类型相同。这是因为,查看您给出的(几乎正确,除了最后一行,它不应该有
foldl(+)
)求值,折叠函数的上一次调用的结果将作为第一个输入传递给下一次调用。因此,类型必须匹配。在
(a->b->c)
中,只有当
a~c
(类型相等)时,第一个参数和结果的类型才匹配,但在这种情况下,由于a和c相等,我们不妨将它们都称为a。假设折叠函数返回类型为a的内容,整个foldl调用的结果也将是类型a,因为它只返回最后一次调用折叠函数的结果。

a
表示累加器值的类型,
b
表示输入中每个元素的类型<代码>(a->b->a)是一个函数,它接受累加器值,即列表中的某个项目,并返回一个新的累加器值,该值可以传递到下一步

初始值的类型必须是
a
,以便函数的第一次调用可以接收累加器值。累加器功能必须采用
a
并返回
a
,以便将累加器值传递到折叠的每个步骤。折叠的最终值必须是
a
,因为这是最终调用折叠函数将返回的累加器类型

(a->b->c)->a->[b]->c
不能表示折叠,因为折叠功能不接受a
c
。折叠功能的输入和输出必须为同一类型,以便累加器可以进入下一个折叠步骤

让我们看一个例子,如果fold函数返回一个
c
,将会发生什么

foldl (+) 0 (1:2:3:[])
foldl (+) (0 + 1) (2:3:[])
foldl (+) ((0 + 1) + 2) (3:[])
foldl (+) (((0 + 1) + 2) + 3) ([])
foldl (+) (((0 + 1) + 2) + 3)
假设我们使用的是动态语言,我们尝试使用
f
折叠。运行时会发生什么

f :: Integer -> Integer -> Bool   -- this is a valid (a -> b -> c)
f acc n = (acc + n) > 0
您可以看到,如果您试图使用不兼容的类型进行累积,则无法进行折叠

foldl f 0 [1]     ~ (0 + 1) > 0            == True :: Bool

foldl f 0 [1, 2]  ~ ((0 + 1) > 0) + 2) > 0 == error - no instance of (+) for Bool
                     \_________/   \
                          |         \
                         Bool      + Integer