导出((。)foldr的类型)

时间:2014-05-01 19:34:30

标签: haskell types unification

我正在尝试手动派生((。)foldr)的类型

(.) ::(b1 -> c1) -> (a1 -> b1) -> a1 -> c1
foldr :: (a2 -> b2 -> b2) -> b2 -> [a2] -> b2

然后:

b1 = a2 -> b2 -> b2
c1 = b2 -> [a2] -> b2

匹配我得到的类型:

((a2 -> b2 -> b2) -> (b2 -> [a2] -> b2)) -> (a1 -> (a2 -> b2 -> b2)) -> a1 -> (b2 -> [a2] -> b2)

但后来我对如何减少这种表达感到困惑。

任何帮助?

Thansks,
安。

2 个答案:

答案 0 :(得分:3)

您正确地找出了(.)(.) foldr的类型。 (.)已应用于一个参数(foldr),因此您可以丢弃((a2 -> b2 -> b2) -> (b2 -> [a2] -> b2)),剩下的是(.) foldr的类型:

(a1 -> a2 -> b2 -> b2) -> a1 -> (b2 -> [a2] -> b2)

确保foldr在丢弃之前可以使用((a2 -> b2 -> b2) -> (b2 -> [a2] -> b2))类型。如果你有匹配的权利,这个检查不会失败,但这是一个很好的理智检查。

答案 1 :(得分:1)

如果我们有

(.)   :: (b -> c) -> (a -> b) -> (a -> c)
foldr :: (x -> y -> y) -> y -> [x] -> y

然后对于(.) foldrb -> c必须与foldr的类型对齐,所以

b             -> c
(x -> y -> y) -> (y -> [x] -> y)

暗示

b ~ (x -> y -> y)
c ~ (y -> [x] -> y)

所以替换回来:

--                 b                       c
(.) foldr :: (a -> (x -> y -> y)) -> (a -> (y -> [x] -> y))

由于->是左关联的,我们可以删除额外的括号:

(.) foldr :: (a -> x -> y -> y) -> (a -> y -> [x] -> y)

如果你想要,你可以更进一步

(.) foldr :: (a -> x -> y -> y) -> a -> y -> [x] -> y

因此,如果我们询问GHCi的类型是什么,我们得到

> :t (.) foldr
(.) foldr :: (a -> a1 -> b -> b) -> a -> b -> [a1] -> b

a ~ aa1 ~ xb ~ y,我们已经得到了正确答案。