Personal tools

Currying

From HaskellWiki

(Difference between revisions)
Jump to: navigation, search
(Section of an infix operator)
(Prelude functions 'curry' and 'uncurry')
Line 1: Line 1:
 
[[Category:Glossary]]
 
[[Category:Glossary]]
Currying is the process of transforming a function that takes multiple arguments into a function that takes just a single argument and returns another function if any arguments are still needed. In Haskell, ''all'' functions are considered curried: that is, ''all functions in Haskell take just single arguments.''
+
Currying is the process of transforming a function that takes multiple arguments into a function that takes just a single argument and returns another function if any arguments are still needed.
  +
  +
<haskell>
  +
f :: a -> b -> c
  +
</haskell>
  +
is the '''curried''' form of
  +
<haskell>
  +
g :: (a, b) -> c
  +
</haskell>
  +
You can convert these two types in either directions with the Prelude functions <hask>curry</hask> and <hask>uncurry</hask>.
  +
<haskell>
  +
f = curry g
  +
g = uncurry f
  +
</haskell>
  +
  +
In Haskell, ''all'' functions are considered curried: That is, ''all functions in Haskell take just single arguments.''
   
 
This is mostly hidden in notation, and so may not be apparent to a new Haskeller. Let's take the function <haskell>div :: Int -> Int -> Int</haskell> which performs integer division. The expression <hask>div 11 2</hask> unsurprisingly evaluates to <hask>5</hask>.
 
This is mostly hidden in notation, and so may not be apparent to a new Haskeller. Let's take the function <haskell>div :: Int -> Int -> Int</haskell> which performs integer division. The expression <hask>div 11 2</hask> unsurprisingly evaluates to <hask>5</hask>.

Revision as of 13:03, 3 July 2007

Currying is the process of transforming a function that takes multiple arguments into a function that takes just a single argument and returns another function if any arguments are still needed.

f :: a -> b -> c

is the curried form of

g :: (a, b) -> c
You can convert these two types in either directions with the Prelude functions
curry
and
uncurry
.
f = curry g
g = uncurry f

In Haskell, all functions are considered curried: That is, all functions in Haskell take just single arguments.

This is mostly hidden in notation, and so may not be apparent to a new Haskeller. Let's take the function
div :: Int -> Int -> Int
which performs integer division. The expression
div 11 2
unsurprisingly evaluates to
5
. But there's more that's going on than immediately meets the untrained eye. It's a two-part process. First,
div 11
is evaluated and returns a function of type
Int -> Int
Then that resulting function is applied to the value
2
, and yields
5
.


You'll notice that the notation for types reflects this: you can read
Int -> Int -> Int
incorrectly as "takes two
Int
s and returns an
Int
", but what it's really saying is "takes an
Int
and returns something of the type
Int -> Int
--that is, it returns a function that takes an
Int
and returns an
Int
. (One can write the type as
Int x Int -> Int
if you really mean the former--but since all functions in Haskell are curried, that's not legal Haskell. Alternatively, using tuples, you can write
(Int, Int) -> Int
, but keep in mind that the tuple constructor
(,)
itself can be curried.)

Much of the time, currying can be ignored by the new programmer. The major advantage of considering all functions as curried is theoretical: formal proofs are easier when all functions are treated uniformly (one argument in, one result out). Having said that, there are Haskell idioms and techniques for which you need to understand currying.

Currying provides a convenient way of writing some functions without having to explicitly name them:

  • (1+)
    (unsugared:
    (+) 1
    ) is the "increment" function,
  • (2*)
    is the "double" function,
  • ("\t"++)
    is the "indent" function,
  • (`elem` "AEIOU")
    is the "is-capital-vowel-in-English" function (ignoring the "sometimes Y").

These are examples of partial application (and of a Section of an infix operator).

Sometimes it's valuable to think about functions abstractly without specifically giving all their arguments: this is the Pointfree style.

Sometimes half the work of the function can be done looking only at the first argument (but there really is only one argument, remember?): see functional dispatch.