Created
January 18, 2013 12:36
-
-
Save oxbowlakes/4564311 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 scalaz._;import Scalaz._; import concurrent._ | |
/* Imagine you have some expensive calculations you wish to make: */ | |
trait RawApi { | |
def expensiveInt: Int = Int.MaxValue | |
def expensiveString: String = "expensive" | |
} | |
/* You wish to write a program using this API */ | |
case class Result(i: Int, s: String) | |
trait Program { | |
val run = Result(_ : Int, _ : String) | |
} | |
/* Now you want your program to run concurrently but you wish to test it single threaded. You need | |
to lift you expensive values into the computation typeclasses. What are they? */ | |
trait ApiM[M[_]] { self: RawApi => | |
def expensiveIntM(implicit Pure: Pure[M]): M[Int] = Pure.pure(self.expensiveInt) | |
def expensiveStringM(implicit Pure: Pure[M]): M[String] = Pure.pure(self.expensiveString) | |
} | |
class ProgramM[M[_]: Monad: Functor] extends ApiM[M] with RawApi with Program { | |
def calc: M[Result] = (expensiveIntM <**> expensiveStringM)(run) | |
} | |
val SingleThreadedProgram = new ProgramM[Identity] | |
val ConcurrentProgram = new ProgramM[Promise] | |
val r: Result = SingleThreadedProgram.calc | |
val f: Promise[Result] = ConcurrentProgram.calc //can send to an actor to process when ready (f to actor[Result] { println } ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment