Reputation: 73
Prelude> :t flip
flip :: (a -> b -> c) -> b -> a -> c
Prelude> :t flip(:)
flip(:) :: [a] -> a -> [a]
I don't think (:)
is a special syntactic sugar for flip
. So what has it done to flip
?
Upvotes: 1
Views: 609
Reputation: 71109
flip (:)
is an application of flip
and (:)
.
Their types are
Prelude> :t flip
flip :: (a -> b -> c ) -> ( b -> a -> c )
Prelude> :t (:)
(:) :: a -> [a] -> [a]
Prelude> :t flip (:)
flip (:) :: [a] -> a -> [a]
flip
just switches the two arguments to a function:
flip f y x = f x y
Thus
flip (:) xs x = (:) x xs = x : xs
Upvotes: 3
Reputation: 477230
The "ingredients" are:
flip :: (a -> (b -> c)) -> (b -> (a -> c))
(:) :: d -> ([d] -> [d])
So here flip
can take a function (of type a -> b -> c
), and it basically converts it to a function of type b -> a -> c
, where thus the "parameters" (technically speaking in Haskell a function has exactly one parameter) are "flipped".
If you write flip (:)
, you thus flip the (:)
function. Since the (:)
function has type d -> [d] -> [d]
, the result is [d] -> d -> [d]
.
We can however perform a more rigorous type inference. Since (:)
is the parameter of a function application with flip
, we know that the type of (:)
should be the same as the type of the parameter of flip
, so:
a -> ( b -> c )
~ d -> ([d] -> [d])
-----------------------
a ~ d, b ~ [d], c ~ [d]
So we conclude that a ~ d
(a
and d
are the same type), b ~ c ~ [d]
. This thus means that the type of flip (:)
is:
flip (:) :: b -> a -> c
or when we perform the replacements to more specific types:
flip (:) :: [d] -> d -> [d]
Semantically flip (:)
takes a list xs
, and an element x
, and returns a list where the element is prepended to the given list (so (x:xs)
).
Upvotes: 6