<p>The 'secret' is in the <code>bindWriter</code> function that drive the <code>Writer</code> monad.</p>
<pre><code>instance Monad Writer where
    return a = Writer a []
    (&gt;&gt;=) = bindWriter
</code></pre>
<p>It is the <code>bindWriter</code> function that aggregates the string list of the <code>Writer</code>s and this happens as part of the execution of the <code>do</code> block which is a list of monadic statements.</p>
<p>For instance, comment out the <code>tell</code> line and the <code>do</code> block in <code>foo''</code> returns</p>
<pre><code>Writer 9 [&quot;number: 2&quot;,&quot;number: 3&quot;,&quot;number: 4&quot;]
</code></pre>
<p>Rewriting the <code>do</code> block to</p>
<pre><code>foo'' x y z = do
     threeInts x y z
</code></pre>
<p>returns the same result. Without return the <code>do</code> block returns the result of the last line (and the compiler complains when it isn't of the right type).</p>
<p>Adding a <code>Writer</code> line returns the <code>Int</code> from the <code>Writer</code>, but the full list of strings:</p>
<pre><code>foo'' x y z = do
     threeInts x y z
     Writer 0 [&quot;adding 0&quot;]
</code></pre>
<p>return</p>
<pre><code>Writer 0 [&quot;number: 1&quot;,&quot;number: 2&quot;,&quot;number: 3&quot;,&quot;adding 0&quot;]
</code></pre>
<p>The <code>tell</code> function causes a string list to be added ignoring the <code>Int</code> part. The <code>threeInts</code> result needs to be captured because it contains the <code>Int</code> result that needs to be returned (and the <code>tell</code> line needs it for the text line).</p>
<p>This monad allows the writing of functions that operate on the Ints and that can emit appropriate messages that are handled in the background.</p>

CC BY-SA 4.0
2021-07-31T21:38:47.910Z
This is what I was missing.  Much appreciated!
Phil Boltt
CC BY-SA 4.0
2021-07-31T18:17:52.847Z
2021-07-31T18:17:52.847Z
vcwebco
<p>I have a question regarding a block of code from th Week04 Plutus Pioneer Program.  The block is in Writer.hs</p>
<pre><code>foo'' :: Writer Int -&gt; Writer Int -&gt; Writer Int -&gt; Writer Int
foo'' x y z = do
    s &lt;- threeInts x y z
    tell [&quot;sum: &quot; ++ show s]
    return s
</code></pre>
<p>For reference,</p>
<pre><code>threeInts :: Monad m =&gt; m Int -&gt; m Int -&gt; m Int -&gt; m Int
threeInts mx my mz =
mx &gt;&gt;= \k -&gt;
my &gt;&gt;= \l -&gt;
mz &gt;&gt;= \m -&gt;
let s = k + l + m in return s

tell :: [String] -&gt; Writer ()
tell = Writer ()

instance Monad Writer where
    return a = Writer a []

number :: Int -&gt; Writer Int
number n = Writer n $ [&quot;number: &quot; ++ show n]
</code></pre>
<p>Why does</p>
<pre><code>foo'' (number 2) (number 3) (number 4)
</code></pre>
<p>return</p>
<pre><code>Writer 9 [&quot;number: 2&quot;,&quot;number: 3&quot;,&quot;number: 4&quot;,&quot;sum: 9&quot;]
</code></pre>
<p>and not</p>
<pre><code>Writer 9 []
</code></pre>
<p>Obviously there are holes in my understanding, but I read the <code>do</code> block as follows:</p>
<ul>
<li>The result of <code>threeInts x y z</code> is <code>Writer 9 [&quot;number: 2&quot;,&quot;number: 3&quot;,&quot;number: 4&quot;]</code></li>
<li>9 is extracted from this to the definition <code>s</code></li>
<li><code>tell [&quot;sum: &quot; ++ show s]</code> results in <code>Writer () [&quot;sum: 9&quot;]</code></li>
<li><code>return s</code> results in <code>Writer 9 []</code></li>
</ul>
<p>I know that <code>return</code> in Haskell is not the same as it is in an imperative language, but I'm failing miserably to grok how to read this block effectively.  The lambda version producing the same result is more explicit and makes sense to me.</p>
<pre><code>bindWriter :: Writer a -&gt; (a -&gt; Writer b) -&gt; Writer b
bindWriter (Writer a xs) f =
  let
    Writer b ys = f a
  in
    Writer b $ xs ++ ys

foo' :: Writer Int -&gt; Writer Int -&gt; Writer Int -&gt; Writer Int
foo' x y z = x `bindWriter` \k -&gt;
             y `bindWriter` \l -&gt;
             z `bindWriter` \m -&gt;
             let s = k + l + m
             in tell [&quot;sum: &quot; ++ show s] `bindWriter` \_ -&gt;
                Writer s []
</code></pre>
<p>I read this backwards where (for my concrete example) <code>Writer 9 []</code> is bound/combined with <code>Writer () [&quot;sum: 9&quot;]</code> which is then bound/combined with <code>Writer 4 [&quot;number: 4&quot;]</code>, <code>Writer 3 [&quot;number: 3&quot;]</code> and <code>Writer 2 [&quot;number: 2&quot;]</code> where the Int values are discarded in the bind process and the &quot;logs&quot; are concatenated.</p>
<p>There is something implicit in the <code>do</code> notation that I'm overlooking or not reading correctly.  Any help appreciated.</p>

<plutus-pioneer-program><haskell><monad>
Understanding do notation with Monads in Plutus Pioneer Week 04
# Understanding do notation with Monads in Plutus Pioneer Week 04

(Asked by: username_0 on 2021-07-31)

I have a question regarding a block of code from th Week04 Plutus Pioneer Program.  The block is in Writer.hs
foo'' :: Writer Int -> Writer Int -> Writer Int -> Writer Int
foo'' x y z = do
    s <- threeInts x y z
    tell ["sum: " ++ show s]
    return s

For reference,
threeInts :: Monad m => m Int -> m Int -> m Int -> m Int
threeInts mx my mz =
mx >>= \k ->
my >>= \l ->
mz >>= \m ->
let s = k + l + m in return s

tell :: [String] -> Writer ()
tell = Writer ()

instance Monad Writer where
    return a = Writer a []

number :: Int -> Writer Int
number n = Writer n $ ["number: " ++ show n]

Why does
foo'' (number 2) (number 3) (number 4)

return
Writer 9 ["number: 2","number: 3","number: 4","sum: 9"]

and not
Writer 9 []

Obviously there are holes in my understanding, but I read the do block as follows:

The result of threeInts x y z is Writer 9 ["number: 2","number: 3","number: 4"]
9 is extracted from this to the definition s
tell ["sum: " ++ show s] results in Writer () ["sum: 9"]
return s results in Writer 9 []

I know that return in Haskell is not the same as it is in an imperative language, but I'm failing miserably to grok how to read this block effectively.  The lambda version producing the same result is more explicit and makes sense to me.
bindWriter :: Writer a -> (a -> Writer b) -> Writer b
bindWriter (Writer a xs) f =
  let
    Writer b ys = f a
  in
    Writer b $ xs ++ ys

foo' :: Writer Int -> Writer Int -> Writer Int -> Writer Int
foo' x y z = x `bindWriter` \k ->
             y `bindWriter` \l ->
             z `bindWriter` \m ->
             let s = k + l + m
             in tell ["sum: " ++ show s] `bindWriter` \_ ->
                Writer s []

I read this backwards where (for my concrete example) Writer 9 [] is bound/combined with Writer () ["sum: 9"] which is then bound/combined with Writer 4 ["number: 4"], Writer 3 ["number: 3"] and Writer 2 ["number: 2"] where the Int values are discarded in the bind process and the "logs" are concatenated.
There is something implicit in the do notation that I'm overlooking or not reading correctly.  Any help appreciated.

**Tags:** plutus-pioneer-program, haskell, monad

---

## 1 answers

### Answer by username_1 on 2021-07-31. Score: 4 | Accepted answer

The 'secret' is in the bindWriter function that drive the Writer monad.
instance Monad Writer where
    return a = Writer a []
    (>>=) = bindWriter

It is the bindWriter function that aggregates the string list of the Writers and this happens as part of the execution of the do block which is a list of monadic statements.
For instance, comment out the tell line and the do block in foo'' returns
Writer 9 ["number: 2","number: 3","number: 4"]

Rewriting the do block to
foo'' x y z = do
     threeInts x y z

returns the same result. Without return the do block returns the result of the last line (and the compiler complains when it isn't of the right type).
Adding a Writer line returns the Int from the Writer, but the full list of strings:
foo'' x y z = do
     threeInts x y z
     Writer 0 ["adding 0"]

return
Writer 0 ["number: 1","number: 2","number: 3","adding 0"]

The tell function causes a string list to be added ignoring the Int part. The threeInts result needs to be captured because it contains the Int result that needs to be returned (and the tell line needs it for the text line).
This monad allows the writing of functions that operate on the Ints and that can emit appropriate messages that are handled in the background.

> **Comments:**
> **username_0**: This is what I was missing.  Much appreciated!  

---

