Skip to content

Instantly share code, notes, and snippets.

@unktomi
Created June 11, 2017 18:16
Show Gist options
  • Save unktomi/908e15aa18fc069fc4f522e6908b2464 to your computer and use it in GitHub Desktop.
Save unktomi/908e15aa18fc069fc4f522e6908b2464 to your computer and use it in GitHub Desktop.
object Prisms {
// Sum type constructors
def left[B, C](x: B): (B=>C)=>C = {
(k) => {
k(x)
}
}
def right[B, C](y: C): (B=>C)=>C = {
(k)=> y
}
// Simulation of call-cc
case class Thrown[A](x: A) extends Throwable
def callCC[P, Q](f: (P=>Q)=>P): P = {
try {
def h(x: P): Q = {
throw Thrown(x)
}
f(h)
} catch {
case Thrown(x) => {
x.asInstanceOf[P]
}
}
}
// Sum type destructor
def either[B, C, X](x: (B=>C)=>C, f: B=>X, g: C=>X): X = {
callCC((raise: X=>C)=> {
def h(y: B): C = {
raise(f(y))
}
g(x(h))
})
}
def main(argv: Array[String]) = {
val x = left(1)
val y = right(true)
either(x, (i:Int)=>println("left: "+(i*3)), (j:Boolean)=>println("right: "+(!j))) // prints left: 3
either(y, (i:Int)=>println("left: "+(i*3)), (j:Boolean)=>println("right: "+(!j))) // prints right: false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment