Last active
February 18, 2019 20:32
-
-
Save erichonorez/f5bca7529c674b8c497c304bbe874d8e to your computer and use it in GitHub Desktop.
Covariance & Contravariance example
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
package example | |
trait Animal { | |
def name: String | |
} | |
case class Cat(name: String) extends Animal | |
case class Dog(name: String) extends Animal | |
trait SmallAnimal extends Animal | |
case class Mouse(name: String) extends SmallAnimal | |
trait Printer[-T] { | |
def print(t: T): String | |
} | |
class AnimalPrinter extends Printer[Animal] { | |
override def print(t: Animal): String = "Animal" + t.name | |
} | |
class CatPrinter extends Printer[Cat] { | |
override def print(t: Cat): String = "Cat " + t.name | |
} | |
object Test { | |
def main: Unit = { | |
val printCat: Cat ⇒ Printer[Cat] ⇒ String = cat ⇒ { | |
printer ⇒ { | |
printer.print(cat) | |
} | |
} | |
print( | |
printCat(new Cat("Jules"))(new AnimalPrinter()) | |
) | |
type A = Cat ⇒ SmallAnimal | |
val a: A = c ⇒ Mouse(name = "Mickey") | |
type B = Animal ⇒ Mouse | |
val b: B = a ⇒ Mouse(name = "Mickey") | |
val c: A = b | |
/* | |
* Liskov substitution principle states that: | |
* if B <: A then everything one can to do with a value of type A | |
* on should also be able to do with a value of type B | |
* | |
* In other words, if (Animal ⇒ Mouse) is a subtype of (Cat ⇒ SmallAnimal) then I should be | |
* able to substitute (Cat ⇒ SmallAnimal) by (Animal ⇒ Mouse). | |
* | |
* In need to have the food of a cat (a function Cat ⇒ SmallAnimal). What I have under my hand is | |
* a function that provide a mouse for all animals (Animal ⇒ Mouse). If it can provide the food for | |
* all animals it can provide the food for a Cat. And because A mouse is a small animal (Mouse <: SmallAnimal) | |
* (Cat ⇒ SmallAnimal) can be substitued by (Animal ⇒ Mouse). | |
*/ | |
c(new Dog("Ya")) // doesn't compile | |
c(new Cat("Ya")) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment