Skip to content

Instantly share code, notes, and snippets.

@philipschwarz
Created September 10, 2017 16:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save philipschwarz/debbe80f7f86f4b7cdc006af27c36eb7 to your computer and use it in GitHub Desktop.
Save philipschwarz/debbe80f7f86f4b7cdc006af27c36eb7 to your computer and use it in GitHub Desktop.
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import scala.io.StdIn.readLine
object Main {
trait Terminal[C[_]] {
def read: C[String]
def write(t: String): C[Unit]
}
type Now[X] = X
object TerminalSync extends Terminal[Now] {
def read: String = readLine("enter some text:")
def write(t: String): Unit = println(t)
}
object TerminalAsync extends Terminal[Future] {
def read: Future[String] = Future{ val l = readLine("enter some text:"); Thread.sleep(2000); l }
def write(t: String): Future[Unit] = Future{ write(t); Thread.sleep(2000) }
}
trait Execution[C[_]] {
def doAndThen[A, B](c: C[A])(f: A => C[B]): C[B]
def create[B](b: B): C[B]
}
implicit class Ops[A, C[_]](c: C[A]) {
def flatMap[B](f: A => C[B])(implicit e: Execution[C]): C[B] =
e.doAndThen(c)(f)
def map[B](f: A => B)(implicit e: Execution[C]): C[B] =
e.doAndThen(c)(f andThen e.create)
}
def echo[C[_]](implicit t: Terminal[C], e: Execution[C]): C[String] =
for {
in <- t.read
_ <- t.write(in)
} yield in
val nowTerminal:Terminal[Now] = TerminalSync
val nowExecution:Execution[Now] = new Execution[Now]{
def doAndThen[A, B](c: Now[A])(f: A => Now[B]): Now[B] = f(c)
def create[B](b: B): Now[B] = b
}
val futureTerminal:Terminal[Future] = TerminalAsync
val futureExecution:Execution[Future] = new Execution[Future]{
def doAndThen[A, B](c: Future[A])(f: A => Future[B]): Future[B] = c flatMap f
def create[B](b: B): Future[B] = Future(b)
}
def main(args: Array[String]): Unit = {
println("text was " + echo(nowTerminal, nowExecution))
println("text was " + Await.result(echo(futureTerminal, futureExecution), 10 seconds)) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment