
Thanks Daniel,
I think I follow what you've written.
(b -> c) -> (b -> c) is the same as (b -> c) -> b > c
and when that is flipped: b -> (b- > c) -> c
Is that right?
Thanks,
Jeff
On 2 March 2011 11:23, Daniel Fischer
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