Skip to content

Instantly share code, notes, and snippets.

@belyaev-mikhail
Created June 16, 2019 19:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save belyaev-mikhail/3033bd22a806090798075c4b7086ce1d to your computer and use it in GitHub Desktop.
Save belyaev-mikhail/3033bd22a806090798075c4b7086ce1d to your computer and use it in GitHub Desktop.
class Covariant<out T>
class Contravariant<in T>
class Invariant<T>
infix fun KType.equiv(that: KType) = isSubtypeOf(that) && isSupertypeOf(that)
@Test
fun mooEver() {
/* Covariant<*> =:= Covariant<Any?> =:= Covariant<out Any?> */
/* Covariant<in Nothing> is an illegal type */
val co: Covariant<*> = Covariant<Any?>()
val co2: Covariant<Any?> = co
/* Contravariant<*> =:= Contravariant<Nothing> =:= Contravariant<in Nothing> */
/* Contravariant<out Any?> is an illegal type */
val contra: Contravariant<*> = Contravariant<Nothing>()
val contra2: Contravariant<Nothing> = contra
/* Invariant<*> =:= Invariant<out Any?> */
val inv: Invariant<*> = Invariant<Any?>() as Invariant<out Any?>
val inv2: Invariant<out Any?> = inv
/* Now, the same with reflection */
val top = KTypeProjection.invariant(Any::class.createType(nullable = true))
val bottom = KTypeProjection.invariant(Nothing::class.createType())
val star = KTypeProjection.STAR
val outtop = top.copy(variance = KVariance.OUT)
val inbottom = bottom.copy(variance = KVariance.IN)
fun covariant(arg: KTypeProjection) =
Covariant::class.createType(arguments = listOf(arg))
fun contravariant(arg: KTypeProjection) =
Contravariant::class.createType(arguments = listOf(arg))
fun invariant(arg: KTypeProjection) =
Invariant::class.createType(arguments = listOf(arg))
/* Covariant<*> =:= Covariant<Any?> =:= Covariant<out Any?> */
assertTrue(covariant(top) equiv covariant(star))
assertTrue(covariant(outtop) equiv covariant(star))
/* Covariant<in Nothing> =:= Covariant<*> WAT??? */
assertTrue(covariant(inbottom) equiv covariant(star))
/* Contravariant<*> !=:= Contravariant<Nothing> WAT??? */
assertFalse(contravariant(bottom) equiv contravariant(star))
/* Contravariant<*> !=:= Contravariant<in Nothing> WAT??? */
assertFalse(contravariant(inbottom) equiv contravariant(star))
/* Contravariant<*> =:= Contravariant<out Any?> WAT??? */
assertTrue(contravariant(outtop) equiv contravariant(star))
/* Invariant<*> =:= Invariant<out Any?> */
assertTrue(invariant(outtop) equiv invariant(star))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment