Search code examples
haskelltypessyntaxargumentstype-signature

Number of arguments in Haskell code and type is different, why?


Can anybody explain the code below, what it does step by step, please. I know it is defining a function and its inputs, but what does (+) do, and why are there three Ints in plus and four Ints in plusplus's type, while it seems like there are only 3 arguments in plusplus's code?

 plus :: Int -> Int -> Int 
 plus = (+)

 plusPlus :: Int -> Int -> Int -> Int
 plusPlus a b c = a + b + c

Solution

  • + is the addition operator. Putting an operator in parentheses, like (+), refers to the addition function itself, as opposed to using + to add two numbers right on the spot. Basically, this:

    plus = (+)
    

    is equivalent to:

    plus a b = a + b
    

    Either way, it is defining plus to be a synonym for +.

    In Haskell, -> is used to separate the types of the arguments, as well as the return value. So,

    plus :: Int -> Int -> Int
    

    is a function which takes two Ints and returns an Int.

    plusPlus :: Int -> Int -> Int -> Int
    

    is a function which takes three Ints and returns an Int.

    The reason why the syntax is the same for the arguments and the return value is due to currying.

    To be really pedantic,

    plus :: Int -> Int -> Int                -- ~  Int -> (Int -> Int)
    

    is a function which takes an Int, and returns a function which takes an Int and returns an Int.

    plusPlus :: Int -> Int -> Int -> Int     -- ~  Int -> (Int -> (Int -> Int))
    

    is a function which takes an Int, and returns a function which takes an Int, and returns a function which takes an Int and returns an Int.

    In practice, it's convenient to speak of Haskell functions as taking multiple arguments. But technically, Haskell functions always take one argument. The argument type is on the left side of ->, and the return type is on the right side of ->, but the return type might itself be another function.