Question

I'm studying Haskell and am trying to understand how to applying the concept of currying to functions. I understand the currying is essentially a means of taking a function with several arguments and applying the function to one argument, returning a function that is applied to the second, and so on... without losing any expressiveness. One tutorial I'm working on asks:

"Write a curried version of 2 * (\x y -> x*y)2 3"

I'm hoping someone can help show me how to work this out. Thanks in advance

Edit: In response to two commenters, I can see that recognising

(\x y -> x*y) :: Num a => a -> a -> a

... is my first step. I have a fairly slow learning curve when it comes to functional programming (also new SO poster so excuse any etiquette I break) ... what would my next step be?

Edit 2: @Mikhail, I see that uncurry applied to the type of the lambda expression would something of the form (given uncurry :: (a -> b -> c) -> (a,b) -> c)

Num a => (a,a) -> a 
Was it helpful?

Solution

Your basic understanding of what currying is is correct. Concretely, it is about transforming a function that takes its arguments as a tuple, such as for example

add :: (Int, Int) -> Int
add    (x, y)     =  x + y

into a function that takes its arguments one at a time:

add' :: Int -> Int -> Int
add'    x      y   =  x + y

This scheme allows you to subject the now-curried function to partial application, i.e., applying it with some but not all of its arguments yet. For example we can have

succ :: Int -> Int
succ =  add' 1

where we apply add' to its first argument and yield a function that still expects the remaining argument.

The inverse transformation is called uncurrying and turns a function that takes it arguments "one by one" into a function that takes its arguments "all at once" as a tuple.

Both transformations can be captured by families of higher-order functions. That is, for binary functions there is

curry :: ((a, b) -> c) -> (a -> b -> c)
curry    f             =  \x y -> f (x, y)

uncurry :: (a -> b -> c) -> ((a, b) -> c)
uncurry    f             =  \(x, y) -> f x y

For ternary functions there is

curry3 :: ((a, b, c) -> d) -> (a -> b -> c -> d)
curry3    f                =  \x y z -> f (x, y, z)

uncurry3 :: (a -> b -> c -> d) -> ((a, b, c) -> d)
uncurry3    f                  =  \(x, y, z) -> f x y z

And so forth.

Now let us have a look at your example:

2 * (\x y -> x * y) 2 3

Here you are multiplying the literal 2 with the result of an application of the function (\x y -> x * y) that multiplies its two arguments x and y. As you can see, this function already takes its arguments "one by one". Hence, it is already curried. So, what is meant in your tutorial if they ask to write a curried version of this expression is beyond me. What we could do is write an uncurried version by having the multiplication function takes it arguments "all at once": (\(x, y) -> x * y). Then we get

2 * (\(x, y) -> x * y) (2, 3)

Now note that one could write (\(x, y) -> x * y) as uncurry (*), which would give us

2 * uncurry (*) (2, 3)

If we also uncurry the first application (or actually applications, plural ;-)) of (*), we yield

uncurry (*) (2, uncurry (*) (2, 3))

I doubt whether this was the intention behind the exercise in your tutorial, but I hope this provides you some insight in currying and uncurrying.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top