# [Haskell-beginners] Function Type Confusion ..

Paul Visschers mail at paulvisschers.net
Tue Jan 27 13:33:35 EST 2009

```The trick is this:
add :: (b -> Int) -> (b -> Int) -> (b -> Int)
is equal to
add :: (b -> Int) -> (b -> Int) -> b -> Int

This is because the function arrow is right-associative. Reading the
function type in the latter way, you can then look at
add f g b = f b + g b
in a new way. f has type (b -> Int), g also has this type. The b has
type b and the function result is an Int.

Intuitively you can look at this function in two ways, as a function
that takes two functions as arguments and then returns a function, or as
a function that takes two functions and a value, and then returns a
value. (You can take one more step and see it as a function that takes
one argument (of type b -> Int) and then returns a function of type (b
-> Int) -> b -> Int.)

Similarly the function can be defined as:
add f g = \b -> f b + g b
which is a more direct implementation of the first type you gave. It's
all equivalent though.

It's actually pretty cool when you get used to it.

Paul

Tom Poliquin wrote:
> I was reading "Arrows and Computation"
>
> http://www.soi.city.ac.uk/~ross/papers/fop.ps.gz
>
> (trying to lose my 'beginner' status) when I saw (on page
> one)
>
> add :: (b -> Int) -> (b -> Int) -> (b -> Int)
> add f g b = f b + g b
>
> It seemed like the type definition was wrong (short at least).
>
> I tried it anyway ..
>
> module Main where
> add :: (b -> Int) -> (b -> Int) -> (b -> Int)
> add f g b = f b + g b
> main = do
>    x <- return \$ add (+2) (+3) 7
>    print x
>
> The program compiles and  runs and produces '19' !
>
> For fun I loaded into ghci and got what I believe is the proper
> type ..
>
>    add :: (b -> Int) -> (b -> Int) -> b -> Int
>
>
> When I try the same thing with something simpler
> (leaving a bit off the type definition)
> I get the expected error (by me) ..
>
> module Main where
> dog :: Int -> Int
> dog a b = a + b
>
> main = do
>    x <- return \$ dog 2 3
>    print x
>
> Main.hs:5:0:
>     The equation(s) for `dog' have two arguments,
>     but its type `Int -> Int' has only one
>
> What am I missing? .. Apparently something fundamental