Skip to content

Instantly share code, notes, and snippets.

@jto
Last active May 28, 2018 19:22
Show Gist options
  • Save jto/d47aeea1532047ac2d555e20a0e838a7 to your computer and use it in GitHub Desktop.
Save jto/d47aeea1532047ac2d555e20a0e838a7 to your computer and use it in GitHub Desktop.
import shapeless.LowPriority
trait Dec[T] { type V }
object Dec {
type ItIsYes
type ItIsNo
implicit def itIsNo[T](implicit l: LowPriority): No[T] = new Dec[T] { type V = ItIsNo }
implicit def itIsYes[T](implicit t: T): Yes[T] = new Dec[T] { type V = ItIsYes }
type Aux[T, V0] = Dec[T] { type V = V0 }
type No[T] = Aux[T, ItIsNo]
type Yes[T] = Aux[T, ItIsYes]
}
sealed trait Not[T]
object Not {
implicit def not[T](implicit d: Dec.No[T]): Not[T] = new Not[T]{}
}
sealed trait Neither[T, A, B]
object Neither {
implicit def neitherAOrB[T, A, B](implicit prfA: Not[T =:= A], prfB: Not[T =:= B]) =
new Neither[T, A, B]{}
}
sealed trait Or[T, A, B]
object Or {
implicit def aOrB[T, A, B](implicit prf: Not[Neither[T, A, B]]) =
new Or[T, A, B]{}
}
object tests {
def string[T](t: T)(implicit prf: T =:= String) = "IsAString"
def notString[T](t: T)(implicit prf: Not[T =:= String]) = "IsNotAtring"
def notnot[T](t: T)(implicit prf: Not[Not[T =:= String]]) = "IsNotNotString"
def commutString[T](t: T)(implicit prf: String =:= T) = "IsAString(C)"
def commutNotString[T](t: T)(implicit prf: Not[String =:= T]) = "IsNotAtring"
def neitherIntOrString[T](t: T)(implicit prf: Neither[T, Int, String]) = "IsIntOrString"
def intOrString[T](t: T)(implicit prf: Or[T, Int, String]) = "IsIntOrString"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment