DEV Community

loading...
Cover image for *Variance Analogy

*Variance Analogy

cacilhas profile image Arĥimedeς ℳontegasppα ℭacilhας ・2 min read

Post from Kodumaro.

German Shepherd dog

The other day, talking to some coworkers, I realised developers unacquainted to functional programming find hard to understand type covariance and contravariance abstractions.

So I thought about an analogy to make it easier.

Type contravariance

Let’s define two classes that represent something easy to get in mind: dogs. Shepherds are dogs, so (in Scala):

class Dog

class Shepherd extends Dog
Enter fullscreen mode Exit fullscreen mode

We have a job for a dog trainer. Think about a Shepherd pack needing to be trained.

The job title is “Shepherd trainer”, but a dog trainer – someone who know how to train every kind of dog – is competent for the job:

class Trainer[-A]

val trainerJob: Trainer[Shepher] = new Trainer[Dog]
Enter fullscreen mode Exit fullscreen mode

That’s okay! But a Shepherd trainer couldn’t take a general dog trainer job, ’cause he has no experience with training other kinds of dog.

This is contravariance:

// If:
implicitly[Shepherd <:< Dog]
// Then:
implicitly[Trainer[Dog] <:< Trainer[Shepherd]]
Enter fullscreen mode Exit fullscreen mode

<:< means “is subclass of,” or: every Shepherd is a Dog too, so every Trainer[Dog] is a Trainer[Shepherd] too.⦆

In Scala we use - to represent contravariance.

Type covariance

Now imagine that we need to hire a dog producer. We’re not interested in what kind of dog he’ll supply, any kind is great.

So a Shepherd producer could apply for the service, ’cause Shepherd dogs are so good as any other.

class Producer[+A]

val producerContract: Producer[Dog] = new Producer[Shepherd]
Enter fullscreen mode Exit fullscreen mode

It’s called covariance:

// If
implicitly[Shepherd <:< Dog]
// Then
implicitly[Producer[Shepherd] <:< Producer[Dog]]
Enter fullscreen mode Exit fullscreen mode

⦅Yet every Producer[Shepherd] is a Producer[Dog] too – he produces only dogs.⦆

In Scala we use + to represent covariance.

Discussion (0)

pic
Editor guide