Created
July 31, 2020 09:01
-
-
Save TobiasRoland/b29c10763c993c5b2caf682801b1e2bb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import WhyIsContravarianceSoHard.{Animal, Cat, Dog, Vet} | |
object WhyIsContravarianceSoHard extends App { | |
//why are contravariance so hard | |
val list: List[Int] = List(1, 2, 3) | |
class Animal | |
class Dog(name: String) extends Animal | |
class Cat(name: String) extends Animal | |
//Question: if Dog <: Animal does List[Dog] <: List[Animal]? THE VARIANCE QUESTION. | |
//if YES, then the type is called COVARIANT | |
val lassie = new Dog("lassie") | |
val hachi = new Dog("hachi") | |
val laika = new Dog("laika") | |
val anAnimal: Animal = lassie // dog | |
val myDogs: List[Animal] = List(lassie, hachi, laika) // list of dogs is a list of animals | |
//if NO, then the type is called INVARIANT - default | |
class MyInvariantList[T] | |
//val myDogsInvariant: MyInvariantList[Animal] = new MyInvariantList[Dog] | |
val myDogsInvariant: MyInvariantList[Animal] = new MyInvariantList[Animal] | |
//HELL NO, or No, quite the opposite - CONTRAVARIANCE | |
class MyContravarianceList[-T] | |
val myContravarianceDogs: MyContravarianceList[Dog] = new MyContravarianceList[Animal] // ?! | |
// a contravariance example | |
trait Vet[-T <: Animal]{ | |
def heal(animal: T): Boolean | |
} | |
val myDog = new Dog("buddy") | |
val myDogVet:Vet[Dog] = VetStation.gimmeADogVet() | |
myDogVet.heal(myDog) | |
val myCat = new Cat("catter") | |
val myCatVet:Vet[Cat] = VetStation.gimmeACatVet() | |
myCatVet.heal(myCat) | |
| |
//contains or creates elements of type T, it should be +T | |
//acts on or consumes elements of type T, it should be -T | |
//covariant concepts: a cage, a garage, a factory, a list | |
//contravariant concepts: a vet, a mechanic, a garbage pit, a function (in terms of arg type) | |
} | |
object VetStation { | |
def gimmeADogVet(): Vet[Dog] = new Vet[Animal] { | |
override def heal(animal: Animal): Boolean = true | |
} | |
def gimmeACatVet(): Vet[Cat] = new Vet[Animal] { | |
override def heal(animal: Animal): Boolean = true | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment