[Haskell-beginners] Understanding the type signature of flip$id

Daniel Fischer daniel.is.fischer at googlemail.com
Wed Mar 2 01:23:40 CET 2011


On Wednesday 02 March 2011 00:43:23, Jeff Lasslett wrote:
>  I just don't understand how passing id to flip results in the
> following type signature:
> 
> Prelude> :t flip$id
> flip$id :: b -> (b -> c) -> c
> 
> I do understand what flip has done to map here:-
> 
> Prelude> :t flip$map
> flip$map :: [a] -> (a -> b) -> [b]
> 
> map take a function and a list and produces a new list.  If map is
> passed to flip the result is a function that takes a list, then a
> function and results in a new list.
> 
> How do we go from flip having this signature:
> 
> Prelude> :t flip
> flip :: (a -> b -> c) -> b -> a -> c
> Prelude>
> 
> and id having
> 
> Prelude> :t id
> id :: a -> a
> Prelude>
> 
> to flip$id looking like flip$id :: b -> (b -> c) -> c   ???
> 
> Thanks,
> Jeff

The point is that the type of id has to be unified with the type of flip's 
(first) argument.

flip :: (a -> b -> c) -> (b -> a -> c)
id :: t -> t

So we have to unify (a -> b -> c) and (t -> t). Fully parenthesized,
a -> b -> c is a -> (b -> c). Now unification yields

t = a
-- id's arg must have the same type as the flip's argument's arg

and

t = (b -> c)
-- id's result must have the same result as flip's argument's result

From that follows a = (b -> c) and *id can be passed to flip only at a more 
restricted type than id's most general type, namely at the type
id :: (b -> c) -> (b -> c)*

So,

flip (id :: (b -> c) -> b -> c) :: b -> (b -> c) -> c



More information about the Beginners mailing list