Skip to content

Instantly share code, notes, and snippets.

@mpilquist
Created April 12, 2012 01:41
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mpilquist/2364137 to your computer and use it in GitHub Desktop.
Save mpilquist/2364137 to your computer and use it in GitHub Desktop.
Initial attempt at using Tony Morris's ReaderWriterStateT monad transformer (see https://gist.github.com/2360532)
object RWS extends App {
trait Pointed[P[_]] {
def point[A](a: A): P[A]
}
trait PointedFunctor[PF[_]] extends Pointed[PF] with Functor[PF]
implicit def listIsMonoid[A]: Monoid[List[A]] = new Monoid[List[A]] {
def id: List[A] = Nil
def op(a1: List[A], a2: List[A]) = a1 ++ a2
}
implicit def listIsPointed: Pointed[List] = new Pointed[List] {
def point[A](a: A) = List(a)
}
implicit def idIsPointedFunctor[A]: PointedFunctor[Id] = new PointedFunctor[Id] {
def point[A](a: A) = Id(a)
def fmap[A, B](f: A => B) =
i => Id(f(i.a))
}
case class Config(port: Int)
def log[R, S, F[_]](msg: String)(implicit FF: PointedFunctor[F]): ReaderWriterStateT[R, List[String], S, F, Unit] = ReaderWriterStateT { case (r, s) =>
FF.point((List(msg.format(r, s)), (), s))
}
def invokeService: ReaderWriterStateT[Config, List[String], Int, Id, Int] = {
ReaderWriterStateT { case (cfg, invocationCount) =>
Id((List("Invoking service with port " + cfg.port), util.Random.nextInt(100), invocationCount + 1))
}
}
val prg = for {
_ <- log("Start - r: %s, s: %s")
res <- invokeService
_ <- log("Between - r: %s, s: %s")
_ <- invokeService
_ <- log("Done - r: %s, s: %s")
} yield res
val Id((logMessages, result, invocationCount)) = prg run (Config(port = 443), 0)
println("Result: " + result)
println("Service invocations: " + invocationCount)
println("Log:%n%s".format(logMessages.mkString("\t", "%n\t".format(), "")))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment