What is polymorphism?

Parametric polymorphism

Nick says:

In this function `head`, it takes a list of `A`’s, and returns an `A`. And it doesn’t matter what the `A` is: It could be `Int`s, `String`s, `Orange`s, `Car`s, whatever. Any `A` would work, and the function is defined for every `A` that there can be.

``````def head[A](xs: List[A]): A = xs(0)
// res1: Int = 1

case class Car(make: String)
// res2: Car = Car(make = "Civic")
``````

Parametric polymorphism refers to when the type of a value contains one or more (unconstrained) type variables, so that the value may adopt any type that results from substituting those variables with concrete types.

Subtype polymorphism

Let’s think of a function `plus` that can add two values of type `A`:

``````def plus[A](a1: A, a2: A): A = ???
``````

Depending on the type `A`, we need to provide different definition for what it means to add them. One way to achieve this is through subtyping.

``````trait PlusIntf[A] {
def plus(a2: A): A
}

def plusBySubtype[A <: PlusIntf[A]](a1: A, a2: A): A = a1.plus(a2)
``````

We can at least provide different definitions of `plus` for `A`. But, this is not flexible since trait `Plus` needs to be mixed in at the time of defining the datatype. So it can’t work for `Int` and `String`.

The third approach in Scala is to provide an implicit conversion or implicit parameters for the trait.

``````trait CanPlus[A] {
def plus(a1: A, a2: A): A
}

def plus[A: CanPlus](a1: A, a2: A): A = implicitly[CanPlus[A]].plus(a1, a2)
``````

This is truely ad-hoc in the sense that

1. we can provide separate function definitions for different types of `A`
2. we can provide function definitions to types (like `Int`) without access to its source code
3. the function definitions can be enabled or disabled in different scopes

The last point makes Scala’s ad-hoc polymorphism more powerful than that of Haskell. More on this topic can be found at Debasish Ghosh @debasishg’s Scala Implicits : Type Classes Here I Come.

Let’s look into `plus` function in more detail.