title: scalaz - function composition - WriterT
body: <p>Let's define a <code>Kleisli</code> on <code>\/</code>:</p>
  
  <pre><code>abstract class MyError
  case class NumericalError(msg: String) extends MyError
  
  // Either is a Monad with two type parameters: M[A,B] which represent left and right respectively
  // Let's create an ad-hoc type
  type EEither[+T] = \/[MyError, T]
  </code></pre>
  
  <p>and one ad-hoc function for testing purposes:</p>
  
  <pre><code>def safeSqrtEither(t: Double): EEither[Double] =
    safeSqrtOpt(t) match {
      case Some(r) =&gt; r.right
      case None =&gt; NumericalError("Sqrt on double is not define if _ &lt; 0").left
    }
  val kSafeSqrtEither = Kleisli.kleisli( (x: Double) =&gt; safeSqrtEither(x) )
  </code></pre>
  
  <p>Function composition works smoothly:</p>
  
  <pre><code>val pipeEither = kSafeSqrtEither &gt;&gt;&gt; kSafeSqrtEither
  val r5b = pipeEither2 run 16.0
  //which gives r5b: EEither[Double] = \/-(2.0)
  </code></pre>
  
  <p>I'd like to add logging:</p>
  
  <pre><code>type LoggedROCFun[I,O] = I =&gt; WriterT[EEither,scalaz.NonEmptyList[String],O]
  val sqrtWithLog: LoggedROCFun[Double, Double] =
    (t: Double) =&gt;
      WriterT.put(kSafeSqrtEither(t))(s"squared $t".wrapNel)
  </code></pre>
  
  <p>which seems having the desired behaviour:</p>
  
  <pre><code>val resA = sqrtWithLog(16.0)
  // resA: scalaz.WriterT[EEither,scalaz.NonEmptyList[String],Double] = WriterT(\/-((NonEmpty[squared 16.0],4.0)))
  </code></pre>
  
  <p>Sleek. However, I am struggling to put together an operator which:</p>
  
  <ul>
  <li>combines the values in the <code>WriterT</code> applying <code>&gt;&gt;&gt;</code></li>
  <li>chains (appends) each log, keeping track of each step made</li>
  </ul>
  
  <p>Desired output:</p>
  
  <pre><code>val combinedFunction = sqrtWithLog &gt;&gt;&gt; sqrtWithLog
  val r = combinedFunction run 16.0
  // r: WriterT(\/-((NonEmpty[squared 16.0, squared 4.0],2.0)))
  </code></pre>
  
  <p>My best shot:</p>
  
  <pre><code>def myCompositionOp[I,A,B](f1: LoggedROCFun[I,A])(f2: LoggedROCFun[A,B]): LoggedROCFun[I,B] =
    (x: I) =&gt; {
      val e = f1.apply(x)
      val v1: EEither[A] = e.value
      v1 match {
          case Right(v)  =&gt; f2(v)
          case Left(err) =&gt;
            val lastLog = e.written
            val v2 = err.left[B]
            WriterT.put(v2)(lastLog)
  
        }
    }
  </code></pre>
  
  <p>In the above I first apply <code>f1</code> to <code>x</code>, and then I pass along the result to <code>f2</code>. Otherwise, I short-circuit to <code>Left</code>.
  This is wrong, because in the case <code>Right</code> I am dropping the previous logging history.</p>
  
  <p><strong>One last Q</strong></p>
  
  <pre><code>val safeDivWithLog: Kleisli[W, (Double,Double), Double] =
    Kleisli.kleisli[W, (Double, Double), Double]( (t: (Double, Double)) =&gt; {
      val (n,d) = t
      WriterT.put(safeDivEither(t))(s"divided $n by $d".wrapNel)
    }
    )
  val combinedFunction2 = safeDivWithLog &gt;&gt;&gt; sqrtWithLog
  val rAgain = combinedFunction2 run (-10.0,2.0)
  // rAgain: W[Double] = WriterT(-\/(NumericalError(Sqrt on double is not define if _ &lt; 0)))
  </code></pre>
  
  <p>Not sure why the logs are not carried through after a pipeline switches to <code>Left</code>. Is it because: </p>
  
  <ul>
  <li>type MyMonad e w a = ErrorT e (Writer w) a is isomorphic to (Either e a, w)</li>
  <li>type MyMonad e w a = WriterT w (Either e) a is isomorphic to Either r (a, w)</li>
  </ul>
  
  <p><a href="https://stackoverflow.com/questions/31674741/customising-composition-of-future-either-and-writer-in-scalaz?rq=1">therefore I have flipped the order</a>? </p>
  
  <p>Sources: <a href="https://gist.github.com/tjweir/3349857" rel="nofollow noreferrer">here</a>, <a href="http://eed3si9n.com/learning-scalaz-day15" rel="nofollow noreferrer">scalaz</a>, <a href="http://virtuslab.com/blog/arrows-monads-and-kleisli-part-i/" rel="nofollow noreferrer">here</a>, and <a href="http://book.realworldhaskell.org/read/monad-transformers.html" rel="nofollow noreferrer">real world haskell on transformers</a> </p>