Created
February 26, 2018 14:19
-
-
Save yannick-cw/26e620aad6d7d1aa39458e630fce091c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.concurrent.{Await, ExecutionContext, Future} | |
import scala.concurrent.duration.Duration | |
object FinalTaglessMath extends App { | |
trait Math[Container[_]] { | |
def value(i: Int): Container[Int] | |
def add(a: Container[Int], b: Container[Int]): Container[Int] | |
} | |
trait Multiplication[Container[_]] { | |
def multi(a: Container[Int], b: Container[Int]): Container[Int] | |
} | |
type Pure[Exp] = Exp | |
object PureMathInterpreter extends Math[Pure] { | |
def value(i: Int): Int = i | |
def add(a: Pure[Int], b: Pure[Int]): Int = a + b | |
} | |
object PureMultInterpreter extends Multiplication[Pure] { | |
def multi(a: Pure[Int], b: Pure[Int]): Pure[Int] = a * b | |
} | |
type Print[Exp] = String | |
object PrintInterpreter extends Math[Print] { | |
def value(i: Int): Print[Int] = s"val: $i" | |
def add(a: Print[Int], b: Print[Int]): Print[Int] = s"($a + $b)" | |
} | |
object PrintMultInterpreter extends Multiplication[Print] { | |
def multi(a: Print[Int], b: Print[Int]): Print[Int] = s"($a * $b)" | |
} | |
class AsyncMathInterpreter(implicit ec: ExecutionContext) extends Math[Future] { | |
def value(i: Int): Future[Int] = Future.successful(i) | |
def add(fa: Future[Int], fb: Future[Int]): Future[Int] = | |
for { | |
a <- fa | |
b <- fb | |
} yield a + b | |
} | |
class AsyncMultInterpreter(implicit ec: ExecutionContext) extends Multiplication[Future] { | |
def multi(fa: Future[Int], fb: Future[Int]): Future[Int] = | |
for { | |
a <- fa | |
b <- fb | |
} yield a * b | |
} | |
class Program[Container[_]](M: Math[Container], Mult: Multiplication[Container]) { | |
import M._ | |
import Mult._ | |
def calculateStuff: Container[Int] = | |
multi(add(value(10), value(1)), value(2)) | |
} | |
println(new Program(PureMathInterpreter, PureMultInterpreter).calculateStuff) | |
println(new Program(PrintInterpreter, PrintMultInterpreter).calculateStuff) | |
import scala.concurrent.ExecutionContext.Implicits.global | |
println( | |
Await.result(new Program(new AsyncMathInterpreter(), new AsyncMultInterpreter()).calculateStuff, Duration.Inf)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment