Skip to content

Instantly share code, notes, and snippets.

@larsrh
Created April 13, 2012 15:09
Show Gist options
  • Save larsrh/2377552 to your computer and use it in GitHub Desktop.
Save larsrh/2377552 to your computer and use it in GitHub Desktop.
(disjoint) unions, second attempt
trait AEither[L <: TList] {
// an `HList` where all elements are functions producing `R`
type Fold[R] = L#ToKList[({ type λ[α] = α => R })#λ]#Down
def fold[R](list: Fold[R]): R
}
case class AEitherCons[H, T <: TList](either: Either[H, AEither[T]]) extends AEither[TCons[H, T]] {
def fold[R](list: Fold[R]): R = either.fold(list.head, (t: AEither[T]) => t.fold[R](list.tail))
}
case class AEitherEnd[T](elem: T) extends AEither[TCons[T, TNil]] {
def fold[R](list: Fold[R]): R = list.head(elem)
}
// Usage
scala> val list = ((x: Int) => "int") :: ((s: String) => "string") :: HNil
scala> val x: AEither[TCons[Int, TCons[String, TNil]]] = AEitherCons(Left(3))
x: AEither[TCons[Int,TCons[String,TNil]]] = AEitherCons(Left(3))
scala> x.fold(list)
res0: java.lang.String = int
// also, this works:
scala> AEitherCons(Right(AEitherEnd("foo"))).fold[String](list)
res3: String = string
// but this doesn't (which is okay, I'd say):
scala> AEitherCons(Left(3)).fold[String](list)
// what would be cool:
val x: AEither[Int :|: String :|: TNil] = AEither[_1]("foo")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment