Skip to content

Instantly share code, notes, and snippets.

@y-yu
Created January 26, 2016 17:10
Show Gist options
  • Save y-yu/4b87cb29919a8b369df2 to your computer and use it in GitHub Desktop.
Save y-yu/4b87cb29919a8b369df2 to your computer and use it in GitHub Desktop.
shift/reset
case class ICont[+R, -O, +A](run: (A => O) => R) {
def runId[I >: A <: O]: R = run { (x: I) => x }
def map[B](f: A => B): ICont[R, O, B] = ICont { k => run(f andThen k) }
def flatMap[E, B](f: A => ICont[O, E, B]): ICont[R, E, B] = ICont { k => run { x => f(x).run(k) } }
}
object ICont {
def point[R, A](x: A): ICont[R, R, A] = ICont { k => k(x) }
// def shift[R, I, J, O, A](f: (A => ICont[I, I, O]) => ICont[R, J, J]): ICont[R, O, A] =
// ICont { k1 =>
// f { x => ICont { k2 => k2(k1(x)) } }.runId
// }
def shift[R, J, O, A](f: (A => O) => ICont[R, J, J]): ICont[R, O, A] =
ICont(k =>
f(k).runId
)
def reset[R, O, A](a: ICont[A, O, O]): ICont[R, R, A] = ICont { k => k(a.runId) }
}
object Main extends App {
type LI = List[Int]
type LLI = List[List[Int]]
// def visit(l: LI): ICont[LLI, LI, LI] = l match {
// case Nil =>
// ICont.shift[LLI, Any, LLI, LI, LI](k =>
// ICont[LLI, LLI, LLI](_ => Nil)
// )
// case (x::rest) =>
// for {
// r <- ICont.shift[LLI, LI, LLI, LI, LI](k =>
// for {
// b <- k(Nil)
// c <- ICont.reset[LLI, LI, LLI](
// visit(rest).flatMap(y => k(y))
// )
// } yield b::c
// )
// } yield x::r
// }
def visit(l: LI): ICont[LLI, LI, LI] = l match {
case Nil =>
ICont.shift[LLI, LLI, LI, LI](k =>
ICont[LLI, LLI, LLI](_ => Nil)
)
case (x::rest) =>
for {
r <- ICont.shift[LLI, LLI, LI, LI](k =>
for {
b <- ICont.point(k(Nil))
c <- ICont.reset[LLI, LI, LLI](
visit(rest).flatMap(y => ICont.point(k(y)))
)
} yield b::c
)
} yield x::r
}
def test[A]: ICont[A, A, LLI] = ICont.reset(visit(List(1, 2, 3)))
test.runId
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment