[Haskell-beginners] Function Type Confusion ..

Brent Yorgey byorgey at seas.upenn.edu
Tue Jan 27 13:39:20 EST 2009


On Tue, Jan 27, 2009 at 09:42:54AM -0800, 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).

Hi Tom, that's a great paper to read!  I think your confusion seems to
stem from this simple fact: every function in Haskell only takes one
argument.

Functions that look like they take multiple arguments, for example

  add :: Int -> Int -> Int
  add x y = x + y

are really one-argument functions which return functions.  In the
above example, 'add' is a function which takes a single Int, and
returns a function as output.  This output function also takes a
single Int and finally returns an Int.  Observe:

Prelude> let add x y = (x + y :: Int)
Prelude> :t add
add :: Int -> Int -> Int
Prelude> :t add 3
add 3 :: Int -> Int
Prelude> :t (add 3) 5
(add 3) 5 :: Int
Prelude> (add 3) 5
8
Prelude> add 3 5
8

So we could also write the type of 'add' like this:

  add :: Int -> (Int -> Int)

and in fact, this add's real type.  Int -> Int -> Int is just an
abbreviation; -> associates to the right, so we can omit parentheses
that occur at the rightmost end of a type.  As you can see above, by
the same token, function application associates to the left, so 'add 3
5' is really just an abbreviation for '(add 3) 5': ie., first apply
'add' to 3, obtaining another function as output, then apply that
function to 5.

By now I'm sure you can see that 

  (b -> Int) -> (b -> Int) -> (b -> Int) 

is exactly the same type as 

  (b -> Int) -> (b -> Int) -> b -> Int.

You can think of something of this type *either* as something which
takes two arguments of type (b -> Int) and returns a function of type
(b -> Int); *or* as something which takes three arguments, two of type
(b -> Int) and one of type b, and returns something of type Int; these
are in fact just two different ways to think about the same thing.

Hope that is helpful!
-Brent


More information about the Beginners mailing list