Last active
December 24, 2015 14:29
-
-
Save jcracknell/6813110 to your computer and use it in GitHub Desktop.
Examples demonstrating scala's bizzare specificity rules as applied to contravariant types.
This file contains 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
class Animal | |
class Cat extends Animal | |
abstract class Whisperer[-A <: Animal] extends (A => Unit) | |
object Whisperer { | |
implicit def animalWhisperer: Whisperer[Animal] = | |
new Whisperer[Animal] { def apply(a: Animal): Unit = { println("animal") } } | |
implicit def catWhisperer: Whisperer[Cat] = | |
new Whisperer[Cat] { def apply(a: Cat): Unit = { println("cat") } } | |
} | |
implicitly[Whisperer[Animal]].apply(new Animal) | |
implicitly[Whisperer[Cat]].apply(new Cat) | |
// animal | |
// animal |
This file contains 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
class Animal | |
class Cat extends Animal | |
abstract class Whisperer[-A <: Animal] extends (A => Unit) | |
trait AnimalWhisperers { | |
implicit def animalWhisperer: Whisperer[Animal] = | |
new Whisperer[Animal] { def apply(a: Animal): Unit = { println("animal") } } | |
} | |
trait CatWhisperers extends AnimalWhisperers { | |
implicit def catWhisperer: Whisperer[Cat] = | |
new Whisperer[Cat] { def apply(a: Cat): Unit = { println("cat") } } | |
} | |
object Whisperer extends CatWhisperers | |
implicitly[Whisperer[Animal]].apply(new Animal) | |
implicitly[Whisperer[Cat]].apply(new Cat) | |
// implicitly[Whisperer[Animal]].apply(new Animal) | |
// implicitly[Whisperer[Cat]].apply(new Cat) | |
// /home/cracknj/git/contravariant-resolution/./3.scala:16: error: ambiguous implicit values: | |
// both method animalWhisperer in object Whisperer of type => this.Whisperer[this.Animal] | |
// and method catWhisperer in object Whisperer of type => this.CatWhisperer | |
// match expected type this.Whisperer[this.Cat] | |
// implicitly[Whisperer[Cat]].apply(new Cat) | |
// ^ | |
// one error found |
This file contains 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
class Animal | |
class Cat extends Animal | |
abstract class Whisperer[-A <: Animal] extends (A => Unit) | |
abstract class CatWhisperer extends Whisperer[Cat] | |
object Whisperer { | |
implicit def animalWhisperer: Whisperer[Animal] = | |
new Whisperer[Animal] { def apply(a: Animal): Unit = { println("animal") } } | |
implicit def catWhisperer: CatWhisperer = | |
new CatWhisperer { def apply(a: Cat): Unit = { println("cat") } } | |
} | |
implicitly[Whisperer[Animal]].apply(new Animal) | |
implicitly[Whisperer[Cat]].apply(new Cat) | |
// /home/cracknj/git/contravariant-resolution/./2.scala:19: error: ambiguous implicit values: | |
// both method animalWhisperer in trait AnimalWhisperers of type => this.Whisperer[this.Animal] | |
// and method catWhisperer in trait CatWhisperers of type => this.Whisperer[this.Cat] | |
// match expected type this.Whisperer[this.Cat] | |
// implicitly[Whisperer[Cat]].apply(new Cat) | |
// ^ | |
// one error found |
This file contains 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
class Animal | |
class Cat extends Animal | |
abstract class Whisperer[-A <: Animal] extends (A => Unit) | |
abstract class CatWhisperer extends Whisperer[Cat] | |
trait AnimalWhisperers { | |
implicit def animalWhisperer: Whisperer[Animal] = | |
new Whisperer[Animal] { def apply(a: Animal): Unit = { println("animal") } } | |
} | |
trait CatWhisperers extends AnimalWhisperers { | |
implicit def catWhisperer: CatWhisperer = | |
new CatWhisperer { def apply(a: Cat): Unit = { println("cat") } } | |
} | |
object Whisperer extends CatWhisperers | |
implicitly[Whisperer[Animal]].apply(new Animal) | |
implicitly[Whisperer[Cat]].apply(new Cat) | |
// animal | |
// cat |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment