Haskell: Flipping a curried dollar operator -
say define function:
f = ($ 5)
then can apply it:
> f (\x -> x ^ 2) 25
its type is:
:t f f :: (integer -> b) -> b
which makes sense, gets function argument, , returns function applied on integer
5
.
now define function:
g = flip f
i expect not make sense, because f
function of single argument.
but, checking type:
:t g g :: b -> (integer -> b -> c) -> c
so g
function of 2 arguments!
applying on values:
> g [2, 4, 6] (\x y -> x:y) [5,2,4,6]
what going on here? flip ($ 5)
mean?
follow types:
($ 5) :: (int -> a) -> flip :: (x -> y -> z) -> y -> x -> z
but since ->
right associative, type x -> y -> z
equivalent x -> (y -> z)
, so
flip :: (x -> (y -> z)) -> y -> x -> z ($ 5) :: (int -> a) ->
so x ~ (int -> a)
, (y -> z) ~ a
, substituting in:
($ 5) :: (int -> (y -> z)) -> (y -> z)
and simplified
($ 5) :: (int -> y -> z) -> y -> z
so
flip ($ 5) :: y -> (int -> y -> z) -> z
which equivalent type you're seeing (although used int
instead of integer
save typing).
what saying type of ($ 5)
gets specialized when passed flip
such takes function of 2 arguments. valid have ($ 5) const
, const :: -> b -> a
, ($ 5) const :: b -> int
. ($ 5)
doing applying 5
an argument function, not the argument function. example of partial application, not of arguments supplied function. that's why can things map (subtract 1) [1, 2, 3]
.
an example of how use flip ($ 5)
is:
> flip ($ 5) 1 (**) 25.0 > flip ($ 5) 1 (-) 4.0 > let f x y = (x, y) > flip ($ 5) 1 f (5, 1)
Comments
Post a Comment