Skip to content

Instantly share code, notes, and snippets.

@JoolsF
Last active February 2, 2019 16:33
Show Gist options
  • Select an option

  • Save JoolsF/f6ebfc9fd5bc333cc53f3e0b88483918 to your computer and use it in GitHub Desktop.

Select an option

Save JoolsF/f6ebfc9fd5bc333cc53f3e0b88483918 to your computer and use it in GitHub Desktop.
Writer Monad example 1
import cats.data.Writer
import cats.instances.vector._ // for Monoid
import cats.syntax.applicative._ // for pure
import cats.syntax.writer._
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
type Logged[A] = Writer[Vector[String], A]
/**
* Example of using Writer Monad to produce seperate logs for two different computations where the logs would otherwise
* be interleaved
*/
def slowly[A](body: => A) =
try body finally Thread.sleep(100)
def factorial(n: Int): Logged[Int] = {
for {
ans <- if(n == 0) {
1.pure[Logged]
} else {
slowly(factorial(n - 1).map(_ * n))
}
_ <- Vector(s"fact $n $ans").tell
} yield ans
}
val Vector((logA, ansA), (logB, ansB)) =
Await.result(Future.sequence(Vector(
Future(factorial(3).run),
Future(factorial(5).run)
)), 5.seconds)
// logA: Vector[String] = Vector(fact 0 1, fact 1 1, fact 2 2, fact 3 6)
// ansA: Int = 6
// logB: Vector[String] = Vector(fact 0 1, fact 1 1, fact 2 2, fact 3 6, fact 4 24, fact 5 120)
// ansB: Int = 120
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment