为什么部分应用程序`foldr id` typecheck?

时间:2016-04-08 16:16:19

标签: haskell types type-inference fold partial-application

在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。它们不应该兼容。

1 个答案:

答案 0 :(得分:10)

因为a -> b -> b实际上是a -> (b -> b)。自id :: a -> a起,这会将ab -> 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)非常好。列表中保存的函数全部叠加,因为输出和输入类型匹配。