[Haskell-cafe] Polymorphism/monomorphism (and the restriction)

Christian Sievers sievers at math2.nat.tu-bs.de
Fri Sep 22 16:35:11 EDT 2006

Aaron McDaid wrote:

> This code experiments with "Int", "Float" and "(Num a) => a", and I 
> tried to print x*2 and x/2 for each. (4::Int)/2 isn't allowed because / 
> isn't defined for Ints.

More exactly: (/) is a member function of the Fractional class, and Int is not
an instance of this class.

> You can see that
>  kN :: (Num a) => a
> took two different types depending on what method ( / or * ) was applied 
> to it.
>  kN / 2 = 2.0
>  kN * 2 = 8
> kN/2 is a Float (it can't use Int as / isn't defined for Int, so it uses 
> Float, for which / is defined).

kN/2 has type  Fractional a => a  (try ":t kN/2" in ghci)
and when you apply it to show, a specific type will be chosen
by defaulting (Haskell report section 4.3.4).
Without an explicit default declaration, Haskell will try first Integer, then
Double.  Integer is not an instance of Fractional, so Double will be used.

You will get the types you claim to get when you add the line
"default (Int,Float)" at the top of your file.

> kN*2 is an Int.

By itself, it's  Num a => a,  then it will default to Integer.

> The above outputs demonstrates polymorphism, doesn't it? i.e. Not only 

Polymorphism (or rather: overloading) and defaulting.

> has the compiler got a variety of types to choose from, but a variety of 
> types can be used at runtime?

It only chooses (i.e. tries in order) the types given in the (posibly implicit)
default declaration.  At runtime it doesn't care about types, but of course
the same polymorphic or overloaded function can be used with different types.

> The interesting thing is that k behaves as a Float in both cases. This 
> is monomorphism isn't it? i.e. the compiler may have a variety of types 
> to choose from, but it picks one and sticks to it for every usage. In 
> summary, k didn't give the same outputs as kN.

Since (/) is used with k, it must be Fractional, so as in kN/2,
defaulting makes it Double.

> I'm fairly new to these lists, so apologies if I'm covering old ground 
> again. My first aim is to understand exactly what polymorphism and 
> monomorphism is and demonstrate corresponding results, before thinking 
> about the restriction.

The type of   map :: (a -> b) -> [a] -> [b]
is polymorphic.
Here we are talking about overloading, also known as
ad-hoc polymorphism.  In Haskell overloaded functions
are recognizable by the context in their type, e.g.:
   abs :: Num a => a -> a

I think I also mixed this up in one of my earlier mails.
Seems we need a glossary.

Christian Sievers

More information about the Haskell-Cafe mailing list