How are co- and contra-variance used in designing business applications?

contravariance, covariance, scala

Solution

The classic example is functions, taking the Scala interface for a function with a single argument:

trait Function1[-T1, +R]

Which is contravariant (the `-`) for the argument, and covariant (the `+`) for the return type.

Why?

Imagine you have these classes:

class Timelord { ... }
class Doctor extends Timelord { ... }

class Enemy { ... }
class Dalek extends Enemy { ... }

If you have a method that takes, as a parameter, a `Doctor => Enemy` function; then it's okay to supply an instance of `TimeLord => Enemy`. It'll still accept instances of `Doctor`.

So `TimeLord => Enemy` is a subclass of `Doctor => Enemy` because `TimeLord` is a superclass of `Doctor`, it's contravariant in that parameter.

Likewise, a function returning a `Dalek` is valid when you need a function returning some `Enemy`, because a `Dalek` is-an `Enemy`

So `Doctor => Dalek` is a subclass of `Doctor => Enemy` because `Dalek` is a subclass of `Enemy`, it's covariant in that parameter.

Problem

I know about using `co-` and `contravariance` in the standard library (e.g. collections and trait `Function`) I wonder how `co-` and `contravariance` are used in design of "real world" business applications.

Original source