Skip to content

Instantly share code, notes, and snippets.

@davidpeklak
Created March 1, 2014 21:27
Show Gist options
  • Save davidpeklak/9297659 to your computer and use it in GitHub Desktop.
Save davidpeklak/9297659 to your computer and use it in GitHub Desktop.
import scala.annotation.tailrec
object MyIo2 {
sealed trait IO[+A] {
def flatMap[B](f: A => IO[B]): IO[B] = this match {
case FlatMap(x, g) => FlatMap(x, (a: Any) => g(a).flatMap(f))
case x => FlatMap(x, f)
}
def map[B](f: A => B): IO[B] =
FlatMap[A, B](this, a => Return(f(a)))
def run: A = IO.run(this)
}
object IO {
def apply[A](a: => A): IO[A] = Suspend(() => Return[A](a))
def join[A](ffa: IO[IO[A]]) = ffa.flatMap(identity)
@tailrec def run[A](io: IO[A]): A = io match {
case Return(a) => a
case Suspend(r) => run(r())
case FlatMap(x, f) => x match {
case Return(a) => run(f(a))
case Suspend(r) => run(r() flatMap f)
case FlatMap(y, g) => run(y flatMap (a => g(a) flatMap f))
}
}
}
case class Return[A](a: A) extends IO[A]
case class Suspend[A](resume: () => IO[A]) extends IO[A]
case class FlatMap[A, B](sub: IO[A], k: A => IO[B]) extends IO[B]
def PrintLine(msg: String): IO[Unit] = IO(println(msg))
val actions: Stream[IO[Unit]] =
Stream.fill(1000000)(PrintLine("Still going..."))
val composite: IO[Unit] =
actions.foldLeft(Return(()): IO[Unit]) {
(acc, a) => acc.flatMap {
_ => a
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment