Question: I'm having trouble understanding curried and uncurried functions. All the sites I Google'd to try to provide me a definition were unclear to me.

In one example I found them saying that

`max 4 5` is the same as `(max 4) 5`

But I don't understand what they're doing. How can you have a function `(max 4)` when max requires 2 parameters? I'm completely lost.

Answer: 
Depending on your background, you may find this paper enlightening: **[How to Make a Fast Curry: Push/Enter vs Eval Apply](http://research.microsoft.com/en-us/um/people/simonpj/Papers/eval-apply/index.htm)**. While it's true that multi-argument functions can be understood as functions which bind a single parameter and return another function: `max = (\a -> (\b -> if a > b then a else b))`, the actual implementation is quite a bit more efficient.

If the compiler knows statically that `max` requires two arguments, the compiler will always translate `max 4 5` by pushing the two arguments on the stack (or in registers) and then invoking `max`. This is essentially the same as how a C compiler would translate `max(4, 5)`.

On the other hand, if for instance `max` is an argument to a higher-order function, the compiler may not know statically how many arguments `max` takes. Perhaps in one instance it takes three, so `max 4 5` is a partial application, or perhaps in another it takes only one and `max 4` generates a new function to which `5` is applied. The paper discusses the two common approaches to handling the case where the arity isn't known statically.
You probably got your answer already, but just to reiterate:

If we have

```
add x y = x + y

```

then we can say the following:

```
add = \ x y -> x + y
add 3 = \ y -> 3 + y
add 3 5 = 3 + 5 = 8

```

You ask "how can `max 3` calculate anything?", and the answer is "it can't". It just gives you another *function*. This function can do something when you call it, but you don't "get an answer" as such until *all* the arguments have been supplied. Until then, you just get functions.

Most of the time, this is just a useful syntactic shortcut. For example, you can write

```
uppercase :: String -> String
uppercase = map toUpper

```

instead of having to say

```
uppercase xs = map toUpper xs

```

Notice that if `map` had its arguments the other way around, we wouldn't be able to do this (you can only curry away the *last* argument, not the \_first), so it can be important to think about which order you define your functions' arguments.

---

I say "most of the time" because this is more than syntax sugar. There are several places in the language where you can handle functions with different numbers of arguments *polymorphically* because of currying. Every function either returns an answer, or another function. If you think of it like a linked list (which either contains the next item of data or the end-of-list marker), you can see how this lets you recursively process functions.

So what the heck do I mean by that? Well, for example, QuickCheck can test functions with *any* number of arguments (provided there's a way to auto-generate test data for each argument). This is possible because function types are curried. Every function either returns another function, or a result. If you think about it like a linked list, you can imagine QuickCheck recursively iterating over the function until no more arguments are left.

The following code snippet may or may not explain the idea:

```
class Arbitrary a where
  autogenerate :: RandomGenerator -> a

instance Arbitrary Int
instance Arbitrary Char
...

class Testable t where
  test t :: RandomGenerator -> Bool

instance Testable Bool where
  test rnd b = b

instance (Arbitrary a, Testable t) => Testable (a -> t) where
  test rnd f = test $ f (autogenerate rnd)

```

If we have a function `foo :: Int -> Int -> Bool`, then this is `Testable`. Why? Well, `Bool` is testable, therefore so is `Int -> Bool`, and therefore so is `Int -> (Int -> Bool)`.

By contrast, each size of tuple is a different size, so you have to write separate functions (or instances) for each and every size of tuple. You can't recursively process tuples, because they don't have a recursive structure.