Created
December 6, 2014 17:34
-
-
Save ceedubs/510a7eb9147c9d27132c to your computer and use it in GitHub Desktop.
Using WriterT for logging of Random => IO[A]
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
object WriterTExample extends App { | |
import scalaz._ | |
import scalaz.effect.IO | |
import scala.util.Random | |
import scalaz.syntax.monad._ | |
type Logged[F[_], A] = WriterT[F, DList[String], A] | |
def log[F[_]](msg: => String)(implicit F: Applicative[F]): Logged[F, Unit] = | |
WriterT.writerT(F.point(DList(msg), ())) | |
/** A random number generator reader can take an instance of Random as input | |
* and run a side effect to produce a result */ | |
type RngReader[A] = Kleisli[IO, Random, A] | |
type LoggedR[A] = Logged[RngReader, A] | |
/** log helper with the type parameter fixed to LoggedR */ | |
def logR(msg: => String): LoggedR[Unit] = | |
log(msg) | |
def randomInt(below: Int): RngReader[Int] = | |
Kleisli(rng => IO(rng.nextInt(below))) | |
val addTwoRandomInt: LoggedR[Int] = for { | |
_ <- logR("start") | |
first <- randomInt(10).liftM[Logged] | |
_ <- logR(s"initialized first: $first") | |
second <- randomInt(10).liftM[Logged] | |
_ <- logR(s"initialized second: $second") | |
_ <- logR("finish") | |
} yield first + second | |
val appOutput: RngReader[String] = | |
addTwoRandomInt.run.map{ case (logs, sum) => | |
(logs :+ s"sum: $sum").toList.mkString("\n") | |
} | |
val app: IO[Unit] = for { | |
rng <- IO(new Random()) | |
output <- appOutput(rng) | |
_ <- IO(println(output)) | |
} yield () | |
app.unsafePerformIO() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment