Type-signature vs. function equation in Haskell - Stack Overflow

After thinking some more about this, I think the full explanation should be something along the lines of:

An Haskell function can only accept a single argument and return one parameter. Haskell allows us to pretend that several arguments are passed, but this form is treated as a series of nested lambda functions.

f x y = x + y

is treated as

(1) f = \x -> \y -> x + y

This treatment is true for lambda functions as well \x y -> x + y is treated as \x -> \y -> x + y

This allows us to treat type declaration as left-associative, that is: f :: Int -> Int -> Int is actually f :: (Int -> (Int -> Int)) which fits exactly to (1) above: f has no arguments, but is returning a function which accepts Int. This function in turn returns a function which accepts another Int, and returns an Int.

This means that if we want to return a function from a function, we don't have to do anything special, since that's Haskell's "default" mode.

This also means that given the type declaration f :: Int -> Int -> Int We can write f's implementatin ("equation") with 0, 1 or 2 parameters. If one or two parameter are specified, the compiler will generate the necessary lambdas to comply with the form f :: (Int -> (Int -> Int))

f = \x -> \y -> x + yf x = \y -> x + y  -- \x -> is generatedf x y = x + y -- \x -> \y is generated

But in each of these cases, the function application appearing to accept two parameters will compile successfully, since it will always be translated to the first form, e.g.

f 4 5 --> (\x -> (\y -> x + y) 5 ) 4

Where the inner function application will return the curried form (x + 5)

This enables partial function application, where we can give f just one parameter and get back a partial function.

Also, changing the precedence in the function type:

f'' :: (Int -> Int) -> Int

changes the meaning - we accept a function getting an Int and returning one as the single parameter, and return an Int.
Assuming we've defined this function somewhere, then calling this function with Integer parameters, e.g.

f'' 4 5

will not compile.

Edit:

Also, even if the last arguments are in parenthesis, or are a type declaration, this holds.

E.g., in the following, the last pair of parenthesis is optional, since if they weren't there the compiler would put them anyway to get to the "lambda'd" form.

t4 :: (Int -> Int) -> (Int -> Int)t4 f i = f i + i

Can be applied thus:

t4 (\x -> x*10) 5

Also, given:

type MyIntInt = Int -> Int

Then:

t5 :: MyIntInt -> MyIntInt

Is equivalent to t4, but confusing, since the meaning of MyIntInt is different in both places. The first one is the type of the first parameter.
The second one is "expanded" into Int -> Int (probably because of the right-associativity of the operator), which means that t5 can appear to accept 0 to 2 parameters in the function equation and function application (while actually always accepting 0 and returning embedded lambdas, as I've detailed above).

E.g. we can write t5 just like t4:

t5 f i = f i + i

解釋為什麼 type signature 和定義看起來不一樣的 function 可以 compile 得過