The first thing that confuses things is Num a => , so we will ignore it now. Instead, consider Int -> Int -> Int , which is one of the possible specializations of the type signature you gave.
Functions are almost always curried in Haskell. This means that a function with multiple arguments is actually a function of one argument, which returns a function that takes the next argument, etc.
-> is the correct associative, so Int -> Int -> Int is the same as Int -> (Int -> Int) .
It also means that this definition
f :: Int -> Int -> Int fxy = x + y
coincides with
f :: Int -> Int -> Int fx = \y -> x + y
In fact, all functions in Haskell take exactly one argument. Tuples also exist, but they are first-class citizens, so they are more than just a list of arguments.
Num a => is a slightly different aspect of the type system. It says that a variable of type a must be an instance of a class of type Num . Common examples of types that are instances of Num include Int and Double . Therefore, Num not a type itself, it is a type class. Num a => represents a restriction on a variable of type a , this is not another argument for the function.
The (+) method is a member of a class of type Num , so you must limit a in such a way as to use (+) . If you try to give f signature a -> a -> a (without restriction), this will not work, because a has no limits, and we donβt know what types it can be. As a result, we could not use (+) on it.
David young
source share