Haskell has two namespaces: one for types, one for terms.

Here is a definition of the identity function that uses distinct names for the type variable and the term variable:

id :: forall a. a -> a id = \x -> x

Here is a version that reuses the same name for both variables:

id :: forall a. a -> a id = \a -> a

The reason we can give two variables the same name is that each lives in its own namespace. There is no shadowing here.

A similar situation arises when it comes to constructors. Here is the unit type that uses distinct names for the type constructor and the data constructor:

data Unit = U

Here is a version that reuses the same name for both constructors:

data Unit = Unit

Haskell uses this style of punning in its standard library and built-in types:

data [a] = [] | a : [a] data (a, b) = (a, b) data () = () data Proxy a = Proxy newtype Identity a = Identity a

You might find it elegant or convenient, but it has caused me nothing but pain for several reasons:

Using distinct names for type constructors and data constructors is not that difficult:

data List a = [] | a : List a data Pair a b = (a, b) data Unit = () data Proxy a = P newtype Identity a = Id a

However, it is probably too late to consider this.

We would be better off if Haskell did not have this style of punning in the first place. Designers of new programming languages, my plea to you: learn from this mistake and resist the temptation of meaningless overloading!