The type of an expression def therefore is Default a => a, or, “any instance of Default”. I can instantiate an instance myself by specifying a type signature:

λ> def ::Int→0
λ> def ::Char→'a'

Or by type inference, meaning that the combination of this expression with other expressions allows the compiler to infer the single correct type instance:

λ> def :"bc"→"abc"
λ> def -2→-2
λ> def ==0→True

But with no information it will be a static compile error:

λ> def
Ambiguous type variable `a' in the constraint:
`Default a' arising from a use of `def' at
<interactive>:1:0-2
Probable fix: add a type signature that fixes these type
variable(s)

Why is value polymorphism beneficial? Some trivial examples follow (and you are trusted to extrapolate to the more sophisticated things that might otherwise obscure the essence of this feature).

The Read class contains a method read which is polymorphic on the return value:

classRead a where read ::String-> a

It parses a data type from a string. Combined with the Show class, together Read and Show make a naive serialization library. In the same way, it would be ambiguous to read without specifying the instance:

λ> read "2"
Ambiguous type variable `a' in the constraint:
`Read a' arising from a use of `read' at
<interactive>:1:0-7
Probable fix: add a type signature that fixes these type
variable(s)

But specifying with a type signature or using type inference are fine:

λ> read "2" ::Int→2
λ> read "2"*3→6

Another example is JSON parsing (the real class is different to this, but introduces questions that are irrelevant to the point of this post).

classJSON a where decode ::String->Result a

The decode function is return-value polymorphic, it can be read like this:

decode :: (JSON a) =>String->Result a

That is, it returns a result (success or fail) with a value which is an instance of the JSON class.

In fact, the literal 1 is also polymorphic with type Num a => a, meaning that the number could be an Integer, a Double, a Rational, or a user-defined type like Scientific. It will be determined by inference or annotation.

Such static value polymorphism is difficult to do in popular languages such as C#, Java, C++, without some kind of proxy objects to explicitly instantiate an object to dereference using generics or templates, and hard to do in Lisp, Python, Ruby and JavaScript without static type systems (although can also be approximated with proxy aka “witness” objects). This is, for example, why implementing the Monad class is rather awkward in other languages.