Haskell 不清楚foldl类型定义
我不太明白为什么(a->b->a)返回a,同时(a->b->a->[b]->a返回a。我想应该是这样的:(a->b->c)->a->[b]->c。有人能根据下面的例子向我解释一下吗。谢谢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
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
不能表示折叠,因为折叠功能不接受ac
。折叠功能的输入和输出必须为同一类型,以便累加器可以进入下一个折叠步骤
让我们看一个例子,如果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