Reputation: 595
I have to find out the type of these functions
(.)(:) :: (a -> b) -> a -> [b] -> [b]
(:(.)) type error
((.):) ::
((:):) ::
(.)(.) ::
(.):: (b ->c )->(a->b)->a->c
(:) :: a->[a]->[a]
I don't know what to do to find the type of ((.):). These are old exam question and i am trying to learn how to find types when functions are composed. I have only been able to solve the first one.
Upvotes: 0
Views: 72
Reputation: 428
You just use the same unification algorithm that the compiler uses (mostly). First you should rewrite the expression into a prefix form, working the ((.):)
example that'd be:
\p -> (:) (.) p
which eta-reduces to
(:) (.)
now
(:) :: a -> [a] -> [a]
(.) :: (y -> z) -> (x -> y) -> x -> z
hence you need to unify (y -> z) -> (x -> y) -> x -> z
with a
which gives us a more specific type for (:)
in the context of (:) (.)
:
((y -> z) -> (x -> y) -> x -> z) -> [(y -> z) -> (x -> y) -> x -> z)] -> [(y -> z) -> (x -> y) -> x -> z)]
as this is plain function application, the rule is
f :: a -> b
x :: a
f x :: b
now that the type of (.)
and the first parameter of the specialised (:)
(intermediate) type are the same, you just cancel them out to get the resulting type for (:) (.)
:
[(y -> z) -> (x -> y) -> x -> z)] -> [(y -> z) -> (x -> y) -> x -> z)]
Upvotes: 1
Reputation:
(.)
has type (b -> c) -> (a -> b) -> a -> c
and (:)
has type a -> [a] -> [a]
.
(x:)
is the same as \xs -> x : xs
. In your case, x
is (.)
and thus has the type of (.)
.
From this we can conclude that ((.):)
has type [(b -> c) -> (a -> b) -> a -> c] -> [(b -> c) -> (a -> b) -> a -> c]
.
GHCi verifies this:
Prelude> :t ((.):)
((.):)
:: [(b -> c) -> (a -> b) -> a -> c]
-> [(b -> c) -> (a -> b) -> a -> c]
Upvotes: 1