Last active
August 29, 2015 14:13
-
-
Save Jazzatola/1105aabaeeb2c865d40d to your computer and use it in GitHub Desktop.
Using covariant and contravariant types to demonstrate the Liskov substitution principle
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 com.example | |
class GrandParent | |
class Parent extends GrandParent | |
class Child extends Parent | |
/* | |
* contravariant parameter p | |
* covariant result r | |
*/ | |
trait Foo[-P, +R] { | |
def f(p: P): R | |
} | |
object Bar { | |
def g(foo: Foo[Parent, Parent]) = ??? | |
} | |
class LiskovSubclass extends Foo[GrandParent, Child] { | |
override def f(p: GrandParent): Child = ??? | |
} | |
class OtherSubclass extends Foo[Child, GrandParent] { | |
override def f(p: Child): GrandParent = ??? | |
} | |
object Main { | |
def main(args: Array[String]) { | |
Bar.g(new LiskovSubclass()) | |
Bar.g(new OtherSubclass()) // does not compile | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I've split co/contra variance and tried to convey the pedagogical-point (so to speak) by naming stuff.