scalaz/scalaz — pull request #94 by YoEight (2012-05-24 21:33:21+00:00)
Title: Monadwriter TypeClass

Partially a port from Haskell MonadWriter.

It pemits to use Writer Monad Transformer computation without type annotations nightmare

This comes with two implementations: WriterT and ValidationT

There is also a special syntax which currently includes:

:++> like WriterT
:++>> like WriterT
written like WriterT
listen : (MonadWriter F, Monoid W) => F[W, (A, W)]

Here is an example

```scala

import scalaz._
import scalaz.syntax.monadWriter._
import scalaz.std.string._
import scalaz.MonadWriter
import scalaz.ValidationT
import scalaz.WriterT._

object Toto extends App {
implicit val monadWriter = ValidationT.validationTMonadWriter[Writer, String, String]

case class Person(firstName: String, age: Int)

def notEmpty(s: String) = Option(s).filter(x => !x.isEmpty && !x.forall(_.isWhitespace)) match {
case Some(r) => monadWriter.successT[String](r)
case None => monadWriter.failureT[String]("Empty String")
}

def majority(age: Int) =
if(age >= 18) monadWriter.successT[Int](age)
else monadWriter.failureT[Int]("This person is not an adult")

def validateData(firstName: String, age: Int) = for {
n <- notEmpty(firstName) :++>> (x => "The first name is => " + x + "\n")
a <- majority(age) :++>> (x => "She is an adult => " + x + "\n")
} yield Person(n, a)

def showMe(v: (Person, String)) {
println("Log produced during computation -------")
println(v._2)
println("Computation result --------------------")
println(v._1)
}

println(validateData("", 17).listen.map(showMe).run.run) // showMe will not be called, no log accumulated
println()
println()
println(validateData("Nath", 5).listen.map(showMe).run.run) // showMe will not be called: log value is "Firstname name is => Nath"
println()
println()
validateData("Mimie", 20).listen.map(showMe)
}

```