Created
June 7, 2020 13:09
-
-
Save ahoy-jon/3ae79722f273be9a06c66ee5f12ea4b7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sealed abstract class Cont[Result, +H] { | |
final def map[H2](fn: H => H2): Cont[Result, H2] = flatMap(h => Cont.pure(fn(h))) | |
final def flatMap[H2](fn: H => Cont[Result, H2]): Cont[Result, H2] = Cont.FlatMapped(this, fn) | |
def apply(fn: H => Result): Result | |
} | |
object Cont { | |
case class Wrap[Result, H](f: (H => Result) => Result) extends Cont[Result, H] { | |
override def apply(fn: H => Result): Result = f(fn) | |
} | |
case class FlatMapped[Result, H1, H2](cont: Cont[Result, H1], next: H1 => Cont[Result, H2]) extends Cont[Result, H2] { | |
override def apply(fn: H2 => Result): Result = | |
cont.apply(h1 => next(h1).apply(fn)) | |
} | |
def pure[R, H](h: H): Cont[R, H] = Wrap(f => f(h)) | |
def from[Result, H](fn: (H => Result) => Result): Cont[Result, H] = Wrap(fn) | |
} | |
def add[R](x: Int, y: Int): Cont[R, Int] = Cont.pure(x + y) | |
def add2[R](x: Int, y: Int): Cont[R, Int] = Cont.from(continue => continue(x + y)) | |
def times[R](x: Int, y: Int): Cont[R, Int] = Cont.pure(x * y) | |
def square[R](x: Int): Cont[R, Int] = times(x, 2) | |
def pyth[R](x: Int, y: Int): Cont[R, Int] = | |
for { | |
x2 <- square(x) | |
y2 <- square(y) | |
z2 <- add(x2, y2) | |
} yield z2 | |
pyth(3, 5)(println) | |
def debug[R, H](cont:Cont[R, H])(f: (H => R)): R = { | |
cont match { | |
case w:Cont.Wrap[R,H] => w(h => { | |
println(s"debug wrap $h") | |
val r = f(h) | |
println(s"debug wrap eval $h => $r") | |
r | |
}) | |
case s:Cont.FlatMapped[R,_, H] => | |
debug(s.cont)(h1 => { | |
println(s"debug flatMap hidden $h1") | |
val r: R = debug(s.next(h1))(f) | |
r | |
}) | |
} | |
} | |
debug[Unit, Int](pyth[Unit](3,4))(println) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment