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.