Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>In order to log during monadic computation, you have to use an instance of Writer monad. Since monad doesn't compose and you want to keep "Validation" effect, you should use a Validation Monad Transformer. I don't know which version of ScalaZ you're using but Scalaz7 (branch scalaz-seven) provides such monad transformer (namely ValidationT).</p> <p>so we get:</p> <pre><code>ValidationT[({type f[x] = Writer[W, x]})#f, A] </code></pre> <p>with W the type of your logger</p> <p><strong>According to your edit</strong>, here's how I'll do it</p> <pre><code>def squareroot(x:Double) = if (x &lt; 0) failureT("Can't take squareroot of negative number") else successT(sqrt(x)) def inverse(x:Double) = if (x == 0) failureT("Can't take inverse of zero ") else successT(1/x) </code></pre> <p>And now, how to use it in a for-comprehension</p> <pre><code>for { y &lt;- squareroot(x).flatMapF(i =&gt; Writer("Squareroot ok", i)) z &lt;- inverse(y).flatMapF(i =&gt; Writer("Inverse ok", i)) } yield z </code></pre> <p>Those snippets might need more type annotations</p> <p><strong>Edited on april 13</strong></p> <p>Here's the correct type annotations for your methods:</p> <pre><code> def squareroot(x:Double):ValidationT[({type f[x] = Writer[String, x]})#f,String,Double] def inverse(x:Double):ValidationT[{type f[x] = Writer[String, x]})#f,String,Double] </code></pre> <p>That way, you can define resultat method like this:</p> <pre><code>def resultat(x:Double) = for { y &lt;- squareroot(x).flatMapF(i =&gt; Writer(", Squareroot ok", i)) z &lt;- inverse(y).flatMapF(i =&gt; Writer(", Inverse ok", i)) } yield z </code></pre> <p>You could also use List[String] as a log type because it's a monoid</p> <p>BTW, I speak French if it can help :-)</p> <p><em><strong>Edit on May 14</em></strong></p> <p>The problem was: The compiler cannot resolve </p> <pre><code>implicitly[Pointed[({ type f[x] = Writer[String, x] })#f]] </code></pre> <p>because WriterT need an instance of Monoid[String] and Pointed[Id]. </p> <pre><code>import std.string._ // this import all string functions and instances import Id._ // this import all Id functions and instances </code></pre> <p>Here is the full executable code</p> <pre><code>import scalaz._ import std.string._ import Id._ import scalaz.WriterT import scalaz.ValidationT import scala.Math._ object ValidationTExample extends Application { type ValidationTWriterAlias[W, A] = ValidationT[({type f[x] = Writer[W, x]})#f, W, A] type WriterAlias[A] = Writer[String, A] def squareroot(x:Double): ValidationTWriterAlias[String, Double] = if (x &lt; 0) ValidationT.failureT[WriterAlias, String, Double]("Can't take squareroot of negative number") else ValidationT.successT[WriterAlias, String, Double](sqrt(x)) def inverse(x:Double): ValidationTWriterAlias[String, Double] = if (x == 0) ValidationT.failureT[WriterAlias, String, Double]("Can't take inverse of zero ") else ValidationT.successT[WriterAlias, String, Double](1/x) def resultat(x:Double) = for { y &lt;- squareroot(x).flatMapF(i =&gt; Writer("Squareroot ok", i)) z &lt;- inverse(y).flatMapF(i =&gt; Writer(", Inverse ok", i)) } yield z println("0 : " + resultat(0.0).run.run) println("-1 : " + resultat(-1.0).run.run) println("4 : " + resultat(4).run.run) } </code></pre> <p><em><strong>Edit on August 14</em></strong> </p> <p>This code is no longer valid in scalaz-seven. ValidationT has been removed since Validation is not a monad. Hopefully, EitherT can be used instead. Besides, a new MonadWriter/ListenableMonadWriter typeclass has been added to alleviate those type annotations.</p> <pre><code>import scalaz._ import std.string._ import syntax.monadwriter._ import scala.Math._ object EitherTExample extends Application { implicit val monadWriter = EitherT.monadWriter[Writer, String, String] def squareroot(x: Double) = if (x &lt; 0) monadWriter.left[Double]("Can't take squareroot of negative number") else monadWriter.right[Double](sqrt(x)) def inverse(x: Double) = if (x == 0) monadWriter.left[Double]("Can't take inverse of zero") else monadWriter.right[Double](1 / x) def resultat(x: Double) = for { y &lt;- squareroot(x) :++&gt; "Squareroot ok" z &lt;- inverse(y) :++&gt; ", Inverse ok" } yield z println("0 : " + resultat(0.0).run.run) println("-1 : " + resultat(-1.0).run.run) println("4 : " + resultat(4).run.run) } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload