Skip to content

Instantly share code, notes, and snippets.

@sergey-scherbina
Created October 23, 2019 01:31
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 sergey-scherbina/ae390175d66d5df64905211aa28c3d7e to your computer and use it in GitHub Desktop.
Save sergey-scherbina/ae390175d66d5df64905211aa28c3d7e to your computer and use it in GitHub Desktop.
object OpenUnion extends App {
trait in[A, B] {
def inj(a: A): B
}
object in {
implicit def inSelf[A]: (A in A) = (a: A) => a
implicit def inHead[A, B]: (A in (A Either B)) = (a: A) => Left(a)
implicit def inRight[A, B, C](implicit r: (A in C)): (A in (B Either C)) =
(a: A) => Right(r.inj(a))
implicit def inLeft[A, B, C](implicit r: (A in B)): (A in (B Either C)) =
(a: A) => Left(r.inj(a))
}
def inj[B] = new {
def apply[A](a: A)(implicit r: (A in B)): B = r.inj(a)
}
def handle[A, B, C](a: (A Either B))(f: A => C): Option[B] =
a.fold(a => Function.const(None)(f(a)), Some(_))
type :|:[A, B] = Either[A, B]
type All = String :|: Int :|: Boolean :|: Double
def handleAll[A](a: A)(implicit r: (A in All)) =
handle(inj(a))(x => println(x + " : String"))
.flatMap(handle(_)(x => println(x + " : Int")))
.flatMap(handle(_)(x => println(x + " : Boolean")))
.map(x => println(x + " : Double"))
handleAll("a")
handleAll(1)
handleAll(true)
handleAll(1.0)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment