Skip to content

Instantly share code, notes, and snippets.

@pandaforme
Last active August 3, 2016 11:42
Show Gist options
  • Save pandaforme/196d1752a0592ba0c152ffc75479411d to your computer and use it in GitHub Desktop.
Save pandaforme/196d1752a0592ba0c152ffc75479411d to your computer and use it in GitHub Desktop.
package writer
import cats.Monoid
case class Writer[A, D](value: A, message: D)(implicit m: Monoid[D]) {
def flatMap[B](f: A => Writer[B, D]): Writer[B, D] = f(value) match {
case Writer(result, d) => Writer(result, m.combine(message, d))
}
def map[B](f: A => B): Writer[B, D] = Writer[B, D](f(value), message)
}
object Monoid {
implicit val StringMonoid = new Monoid[String] {
override def empty = ""
override def combine(s1: String, s2: String) = {
val delimiter =
if (s1 == empty || s2 == empty) ""
else ", "
s1 + delimiter + s2
}
}
implicit def ListMonoid[A]: Monoid[List[A]] = new Monoid[List[A]] {
def combine(a1: List[A], a2: List[A]) = a1 ::: a2
def empty = Nil
}
}
object Operators {
implicit class ops[A](a: A) {
def :->[D](d: D)(implicit m: Monoid[List[D]]) = Writer(a, List(d))
}
}
object Writer extends App {
import Monoid._
private val writer = for {
w1 <- Writer(5, List("start 5"))
w2 <- Writer(w1 + 3, List("added three"))
w3 <- Writer(w2 * 5, List("times five"))
w4 <- Writer(w3 + 2, List("plusTwo"))
} yield {
w4
}
println(writer.value)
writer.message foreach println
// use operator `:->`
import Monoid._
import Operators._
private val writer1 = for {
w1 <- 5 :-> "start 5"
w2 <- w1 + 3 :-> "added three"
w3 <- w2 * 5 :-> "times five"
w4 <- w3 + 2 :-> "plusTwo"
} yield {
w4
}
println(writer1.value)
writer1.message foreach println
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment