Skip to content

Instantly share code, notes, and snippets.

@satyagraha
Created June 29, 2016 09:32
Show Gist options
  • Save satyagraha/467ce5c77b5d62c6aa45d5d500f0a4e4 to your computer and use it in GitHub Desktop.
Save satyagraha/467ce5c77b5d62c6aa45d5d500f0a4e4 to your computer and use it in GitHub Desktop.
package org.shape
object TypeEqualityChecks {
trait Bool {
type not <: Bool
}
trait True extends Bool {
type not = False
}
trait False extends Bool {
type not = True
}
//Defining
def unexpected: Nothing = sys.error("Unexpected invocation")
trait =:!=[A, B]
implicit def neq[A, B]: A =:!= B = new =:!=[A, B] {}
implicit def neqAmbig1[A]: A =:!= A = unexpected
implicit def neqAmbig2[A]: A =:!= A = unexpected
//Typeclass that SHOULD witness that two types are equal by "returning" a Bool type.
trait TypeEquality[A, B] {
type Out <: Bool
def out: Boolean
}
//Implicit definitions
object TypeEquality {
implicit def eq[A, B](implicit eq: A =:= B) = new TypeEquality[A, B] { type Out = True; def out = true }
implicit def neq[A, B](implicit eq: A =:!= B) = new TypeEquality[A, B] { type Out = False; def out = false }
}
}
object TypeEqualityChecksApp extends App {
import TypeEqualityChecks._
val sii = implicitly[TypeEquality[Int, Int]]
val sis = implicitly[TypeEquality[Int, String]]
//This runs flawlessly
println(sii.out)
println(sis.out)
//val checkTypes = implicitly[False =:= s.Out] // DOES NOT COMPILE
//val checkTypes2 = implicitly[True =:= s.Out] // DOES NOT COMPILE
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment