Currying in Haskell
In Haskell, each function only takes one argument. Currying is used to get functions of multiple arguments.
Consider the following function:
add x y = x + y
Then, the type of add
is:
add :: (Num a) => a -> a -> a
which can be written:
add :: (Num a) => a -> (a -> a)
That is, add
takes a number as a parameter and returns a (function that takes a number and returns a function).
We can partially apply functions:
inc = add 1
Then, inc
is a function \y -> 1 + y
, because x
has been filled in with the value 1 that we passed as a parameter.
I think of it like this: A function takes parameters, e.g. x
and y
, and does some operations on them, e.g. x+y
. When I pass a value, e.g. 1, for a parameter, e.g. x
to a function, I am getting back a new function that will do those same operations, but with the value filled in for the dummy variable, i.e. x
.
1. How does haskell know how to partially apply user defined functions?
Functions in haskell are defined with a lot of syntactic sugar. Functions can be written as lambda expressions:
\x -> x + 3
Haskell lets us name a function:
add3 = \x -> x + 3
Syntactic sugar lets us write the function in place:
add3 x = x + 3
For multi-argument functions such as:
\x -> \y -> x + y
we can hide the currying
\x y -> x + y
and give a name as before:
add x y = x + y
This should make it clearer why Haskell knows how to interpret later calls such as add 3
.
2. What if I want to change the order of arguments?
Consider the following function:
f :: arg1 -> arg2 -> arg3 -> arg4 -> result
Then, to switch arguments 3 and 4, define g
:
g a b d c = f a b c d
flip
can do this for two arguments.
2.0.1. A question about partial application
f :: Int -> Int -> Int f = \x -> if x==0 then \y -> y else \y -> 2 flip f 1
The fully applied function flip f 1 0
returns the same as the fully applied function f 0 1
, but what do the partial applications flip f 1
and f 0
look like?
2.0.2. A possible answer?
Is it always the case that functions can be re-written so that the arguments come first? E.g.
f = \x -> \y -> if x==0 then y else 2
If so, then re-ordering arguments is conceptually easy to understand. I think this may be the case, but I am not sure if there exists a function which cannot be written in this form.