Last active
October 13, 2015 04:38
-
-
Save nsfyn55/4141034 to your computer and use it in GitHub Desktop.
Contravariance Example
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
/* | |
Invariant: | |
String is subclass of Object but in java | |
List<String> is not a subclass of List<Object> | |
Covariant | |
String in scala is a subclass of Object | |
List[String] is a subclass of List[Object] | |
Contravariant | |
Will accept types that are super classes of | |
the proposed type. | |
class X[-A] | |
val x: X[String] = new X[Object] | |
*/ | |
//cool, but why: | |
/*** Covariant FAIL ***/ | |
class Output[+A]{def write(a:A) = /* Do some writing */} | |
def writeObject(out: Output[Object]) = out.write("hello") | |
/* | |
The code below fails because as defined it only | |
accepts types covariant to List[String]. The call to | |
"write" attempts to pass a Object[Object] which is | |
itself covariant to Output[List[String]] but its the | |
call write that fails because the type passed is defined | |
as Output[List[String]] and you are attempting to pass | |
it a String. | |
Right now we have this resolution: | |
writeObject(accepts anything covariant to Object) | |
write(accepts anything covariant to List[String]) | |
*/ | |
writeObject(new Output[List[String]]) | |
/********************/ | |
/** Contravariant Solution ***/ | |
class Output[-A]{def write(a:A) = /* Do some writing */} | |
def writeObject(out: Output[Object]) = out.write("hello") | |
//This now causes type mismatch | |
//writeObject(new Output[List[String]]) | |
writeObject(new Output[Any]) | |
/* | |
This now works because write will accept any object that is a | |
super class of Object and write accepts anything of type a | |
so you end up with this resolution: | |
writeObject(accepts anything that is a supertype to Object) | |
write(accepts anything that is a supertype to Object) | |
*/ | |
/******************************/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment