Skip to content

Instantly share code, notes, and snippets.

@larsrh
Created April 13, 2012 11:12
Show Gist options
  • Save larsrh/2375930 to your computer and use it in GitHub Desktop.
Save larsrh/2375930 to your computer and use it in GitHub Desktop.
(disjoint) unions
// Situation now
object UnionTypes {
type ![A] = A => Nothing
type !![A] = ![![A]]
trait Disj { self =>
type D
type t[S] = Disj {
type D = self.D with ![S]
}
}
type t[T] = {
type t[S] = (Disj { type D = ![T] })#t[S]
}
type or[T <: Disj] = ![T#D]
type Contains[S, T <: Disj] = !![S] <:< or[T]
type ∈[S, T <: Disj] = Contains[S, T]
}
scala> import UnionTypes._
import UnionTypes._
// First of all, such a union is not disjoint, e.g. t[Int]#t[Int] <-> t[Int]
// also, this is possible:
scala> def size[T](t: T)(implicit ev: T ∈ t[Int]#t[String]) = t match {
case _: Float => "buh"
}
scala> size(0)
scala.MatchError: 0 (of class java.lang.Integer)
// What I'd like to have is:
/*
def size[T](t: T)(implicit ev: T ∈ Int :|: String :|: EitherNil) = ev(t) match {
case Left(x) => // x is Int
case Right(Left(x)) => // x is String
}
*/
// or maybe nicer:
/*
def size[T](t: T)(implicit ev: T ∈ Int :|: String :|: EitherNil) = t.fold(
((x: Int) => 0) ::
((x: String) => 0) ::
HNil
)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment