Skip to content

Instantly share code, notes, and snippets.

@tonymorris
Created November 5, 2013 23:57
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tonymorris/7328537 to your computer and use it in GitHub Desktop.
Save tonymorris/7328537 to your computer and use it in GitHub Desktop.
Pure-functional IO in Scala
sealed trait IOOperation[A] {
def map[B](f: A => B): IOOperation[B] =
this match {
case PutChar(c, a) =>
PutChar(c, f(a))
case GetChar(g) =>
GetChar(f compose g)
}
}
case class PutChar[A](c: Char, a: A) extends IOOperation[A]
case class GetChar[A](f: Char => A) extends IOOperation[A]
sealed trait IO[A] {
def map[B](f: A => B): IO[B] =
this match {
case Done(a) =>
Done(f(a))
case More(a) =>
More(a map (_ map f))
}
def flatMap[B](f: A => IO[B]): IO[B] =
this match {
case Done(a) =>
f(a)
case More(a) =>
More(a map (_ flatMap f))
}
}
case class Done[A](a: A) extends IO[A]
case class More[A](a: IOOperation[IO[A]]) extends IO[A]
object IO {
def putChar(c: Char): IO[Unit] =
More(PutChar(c, Done(())))
def getChar: IO[Char] =
More(GetChar(Done(_)))
}
object Program {
import IO._
def program: IO[Unit] =
for {
c1 <- getChar
c2 <- getChar
_ <- putChar(c1)
_ <- putChar(c2)
} yield ()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment