Skip to content

Instantly share code, notes, and snippets.

@channingwalton
Last active October 30, 2016 22:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save channingwalton/434cdea8693898faeacb to your computer and use it in GitHub Desktop.
Save channingwalton/434cdea8693898faeacb to your computer and use it in GitHub Desktop.
Alternatives to GADTs in Scala
// No case classes
object Consoles {
trait ConsoleAlg[F[_]] {
def readLine: F[Option[String]]
def printLine(line: String): F[Unit]
}
trait Console[+A] {
def run[F[+ _]](F: ConsoleAlg[F]): F[A]
}
object Console {
val readLine: Console[Option[String]] = new Console[Option[String]] {
def run[F[+ _]](F: ConsoleAlg[F]): F[Option[String]] = F.readLine
}
def printLine(line: String): Console[Unit] = new Console[Unit] {
def run[F[+ _]](F: ConsoleAlg[F]): F[Unit] = F.printLine(line)
}
}
}
// With case classes and a visitor
object ConsoleVisitor {
trait ConsoleAlg[F[_]] {
def readLine: F[Option[String]]
def printLine(line: String): F[Unit]
}
trait Console[+A] {
def run[F[+ _]](F: ConsoleAlg[F]): F[A]
}
case object ReadLine extends Console[Option[String]] {
def run[F[+ _]](F: ConsoleAlg[F]): F[Option[String]] = F.readLine
}
case class PrintLine(line: String) extends Console[Unit] {
def run[F[+ _]](F: ConsoleAlg[F]): F[Unit] = F.printLine(line)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment