在Haskell中,我不明白为什么部分应用程序foldr id
类型检查。
相关类型
> :t foldr id
foldr id :: a -> [a -> a] -> a
> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
> :t id
id :: a -> a
foldr
的第一个参数是(a->b->b)
。相比之下,id
的类型为a->a
。它们不应该兼容。
答案 0 :(得分:10)
因为a -> b -> b
实际上是a -> (b -> b)
。自id :: a -> a
起,这会将a
与b -> b
统一起来,因此我们得到了
id :: c -> c -- type variable consistently renamed for uniqueness
foldr :: (a -> (b -> b)) -> b -> [ a ] -> b | c ~ a , c ~ b->b
foldr id :: b -> [ c ] -> b
foldr id :: b -> [b -> b] -> b
这就是全部。
那它是做什么用的?
foldr f z [x,y,...,n] = f x (f y (... (f n z)...))
foldr id z [x,y,...,n] =
= id x (id y (... (id n z)...))
= x ( y (... ( n (id z))...))
= ( x . y . ... . n . id ) z
= foldr (.) id [x,y,...,n] z
因此foldr id = foldr ($) = flip (foldr (.) id)
非常好。列表中保存的函数全部叠加,因为输出和输入类型匹配。