Home > other >  syntax inconsistency when declaring a Function Type
syntax inconsistency when declaring a Function Type

Time:10-25

If i'm creating a function, let's take the simplest example:

add x y = x   y

if i want to add a Function Type declaration before, for clarity sake

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

I get a compile error:
"Couldn't match expected type ‘Int’ with actual type ‘(Int, Int) -> (Int, Int)’".
"The equation(s) for ‘add’ have two arguments, but its type ‘(Int, Int) -> Int’ has only one"

but it compiles flawlessly if i correct it to

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

coming from other languages, i actually think it's clearer to use the second form with parenthesis, but in my opinion, both ways should work

1 - what is the reason for not working the first way?
2 - i find the error messages completely confusing so, maybe, the error happens for another reason i don't understand

CodePudding user response:

what is the reason for not working the first way?

In the first expression your type says it takes a 2-tuple as single parameter, and it returns the sum of the two items. But in the "body" of the function, you specify add x y = x y hence you construct a function that takes a parameter x that will return a function that will take a parameter y which maps to x y.

In Haskell all functions take one parameter. Indeed, your add function takes one parameter x. It is short for:

add x = \y -> x   y

It thus returns a function that will take a parameter y and then maps y to x y. If you thus construct a function f = add 2, then f will take the parameter y, and map this on 2 y.

The arrow is a right-associative operator. This means that Int -> Int -> Int is short for Int -> (Int -> Int), it thus is a function that maps an Int to another function.

You can see the syntax of languages like Java where they call f (x, y) basically as calling the function f with one object: a 2-tuple with x and y as its two elements.

  • Related