Why do Haskell type signature declarations have multiple arrows?

haskell, syntax, types

Solution

Because of currying. Think about the type of this:

add 3 :: Integer -> Integer

If you give `add` one number it returns a function that maps an `Integer` to another integer. So you could do this:

map (add 3) [1..10]

It doesn't make sense to treat arguments differently from return types with partial application.

EDIT to clarify

I think bheklilr makes a good point that the type signature can be read like this

add :: Integer -> (Integer -> Integer)

We can take a function with more arguments, `zipWith3` because it is the only one I can really think of.

zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]

If we just read what this does it takes a function that takes 3 values and returns a fourth and then 3 lists of those values respectively and it returns a list of the fourth value. Trying it out.

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

Prelude>zipWith3 add3 [1] [2] [3]
[6]

Although, in this case all the values are of type `Int` it still demonstrates the point.

Now what if we don't give it all the lists? What if we give it no lists just `add3`.

zipWith3 add3 :: [Int] -> [Int] -> [Int] -> [Int]
zipWith3 add3 :: [Int] -> ([Int] -> [Int] -> [Int])
zipWith3 add3 :: [Int] -> [Int] -> ([Int] -> [Int])

So, now we have a function that takes 3 lists and returns a list. But this is also a function that takes a list are returns a function that takes 2 lists and returns a list. There is no way to distinguish between them really.

(zipWith3 add3) [1,2] [3,4] [5,6] :: [Int]
(zipWith3 add3) [1,2] :: [Int] -> [Int] -> [Int]

See where I'm going with this? There is no distinction between arguments are return types.

Problem

Sorry this is worded poorly, but it's hard to describe. I guess I'll just jump to the example: ``` add :: Integer -> Integer -> Integer add x y = x + y ``` why is it: ``` :: Integer -> Integer -> Integer ``` instead of: ``` :: Integer, Integer -> Integer ``` the arrow is the "Function type-mapping operator", not some kind of separator, no?

Original source