<div dir="ltr"><div>Fully expanding your program might help. One of the great things about Haskell is equational reasoning: if two things have been declared equal, you can substitute one for the other.</div><div><br></div><div>First, let's desugar that <font face="monospace, monospace">do</font> notation to the equivalent bind chain:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">multWithLog =<br>  logNumber 3 >>= \a -><br>    logNumber 5 >>= \b -><br>      return (a*b)</font></blockquote><div><br></div><div>Evaluate the <font face="monospace, monospace">logNumber</font> and <font face="monospace, monospace">return</font> calls to normal form from their definitions, also considering the monoid definitions of <font face="monospace, monospace">(++)</font> and <font face="monospace, monospace">mempty</font> for lists:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="monospace, monospace">multWithLog =</font></div><div><span style="font-family:monospace,monospace">  </span><span style="font-family:monospace,monospace;font-size:12.8px">Writer (3, ["Got number: 3"]) >>= \a -></span><br></div><div><span style="font-size:12.8px"><font face="monospace, monospace">    Writer (5, ["Got number: 5"]) >>= \b -></font></span></div><div><span style="font-family:monospace,monospace;font-size:12.8px">      Writer (a*b, [])</span><br></div></blockquote><div><br></div><div><span style="font-size:12.8px">Now, refer to the definition of <font face="monospace, monospace">(>>=)</font> for <font face="monospace, monospace">Writer</font> (as shown in LYAH):</span></div><div><span style="font-size:12.8px"><br></span></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><span style="font-size:12.8px"><font face="monospace, monospace">(Writer (x, v)) >>= f = let (Writer (y, v')) = f x in Writer (y, v `mappend` v')</font></span></div></blockquote><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">Rewritten as a lamba (and replacing </span><font face="monospace, monospace">`mappend`</font> with <font face="monospace, monospace">(++)</font> for brevity)<span style="font-size:12.8px">, this becomes:</span></div><div><span style="font-size:12.8px"><br></span></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="monospace, monospace"><span style="font-size:12.8px">\(Writer (x, v)) f -></span><span style="font-size:12.8px"> </span><span style="font-size:12.8px">let (Writer (y, v')) = f x in Writer (y, v++v')</span></font></div></blockquote><div><span style="font-size:12.8px"><br></span></div><div>It's no longer an infix function, so we'll have to shift things around a little. Here's what it expands to:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><font face="monospace, monospace">multWithLog =</font></div></div><div><div><font face="monospace, monospace">  (\(Writer (x, v)) f ->                -- \</font></div><div><font face="monospace, monospace">      let (Writer (y, v')) = f x        -- |</font><span style="font-family:monospace,monospace"> </span><span style="font-family:monospace,monospace">bind</span></div><div><font face="monospace, monospace">      in Writer (y, v++v'))             -- /</font></div></div><div><div><font face="monospace, monospace">    (Writer (3, ["Got number: 3"]))     -- Writer (x, v)</font></div></div><div><div><font face="monospace, monospace">    (\a ->                              </font><span style="font-family:monospace,monospace">-- f</span></div><div><font face="monospace, monospace">        (\(Writer (x2, v2)) f2 ->       -- \</font></div><div><font face="monospace, monospace">        let (Writer (y2, v2')) = f2 x2  -- |</font><span style="font-family:monospace,monospace"> </span><span style="font-family:monospace,monospace">bind</span></div><div><font face="monospace, monospace">        in Writer (y2, v2++v2'))        -- /</font></div></div><div><div><font face="monospace, monospace">      (Writer (5, ["Got number: 5"]))   -- Writer (x2, v2)</font></div></div><div><div><font face="monospace, monospace">      (\b -> Writer (a*b, []))          -- f2</font></div></div><div><div><font face="monospace, monospace">    )                                   -- (end f)</font></div></div></blockquote><div><br></div><div>Now it's just a matter of simplification. Let's start by eliminating the first argument of each bind, i.e. <font face="monospace, monospace">(Writer (x,v))</font>, by substituting with concrete values.</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><div><font face="monospace, monospace">multWithLog =</font></div><div><font face="monospace, monospace">  (\f ->                                        -- \ partially</font></div><div><font face="monospace, monospace">      let (Writer (y, v')) = f 3                -- | applied</font></div><div><font face="monospace, monospace">      in Writer (y, ["Got number: 3"]++v'))     -- / bind</font></div><div><font face="monospace, monospace">    (\a ->                                      -- f</font></div><div><font face="monospace, monospace">        (\f2 ->                                 -- \ partially</font></div><div><font face="monospace, monospace">        let (Writer (y2, v2')) = f2 5           -- | applied</font></div><div><font face="monospace, monospace">        in Writer (y2, ["Got number: 5"]++v2')) -- / bind</font></div><div><font face="monospace, monospace">      (\b -> Writer (a*b, []))                  -- f2</font></div><div><font face="monospace, monospace">    )                                           -- (end f)</font></div></div></div></blockquote><div><br></div><div>Substitute <font face="monospace, monospace">f2</font>, and eliminate both <font face="monospace, monospace">\f2</font> and <font face="monospace, monospace">\b</font> in the same way:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="monospace, monospace">multWithLog =</font></div><div><font face="monospace, monospace">  (\f -></font></div><div><font face="monospace, monospace">      let (Writer (y, v')) = f 3</font></div><div><font face="monospace, monospace">      in Writer (y, ["Got number: 3"]++v'))</font></div><div><font face="monospace, monospace">    (\a -></font></div><div><font face="monospace, monospace">      </font><span style="font-family:monospace,monospace">let (Writer (y2, v2')) = Writer (a*5, [])  -- applied f2</span></div><div><font face="monospace, monospace">      in Writer (y2, ["Got number: 5"]++v2')</font></div><div><font face="monospace, monospace">    )<br></font></div></blockquote><div><br></div><div>With a full match on the inner let block, that can also be eliminated:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><font face="monospace, monospace">multWithLog =</font></div></div><div><div><font face="monospace, monospace">  (\f -></font></div></div><div><div><font face="monospace, monospace">      let (Writer (y, v')) = f 3</font></div></div><div><div><font face="monospace, monospace">      in Writer (y, ["Got number: 3"]++v'))</font></div></div><div><div><font face="monospace, monospace">    (\a -> Writer (a*5, ["Got number: 5"]++[]))</font></div></div></blockquote><div><br></div><div>I'll forego the last few substitutions. If it's still not clear how you get to the final output, you should run through them yourself. You'll eventually reach a static definition of the result -- which shouldn't really be surprising, since there were no arguments to this "function" and its type doesn't contain <font face="monospace, monospace">-></font> anywhere. :)</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 26, 2017 at 1:34 PM, Olumide <span dir="ltr"><<a href="mailto:50295@web.de" target="_blank">50295@web.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 26/01/17 16:02, David McBride wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
runWriter multWithLogTuple<br>
</blockquote>
((3,5,10),["Got number: 3","Got number: 5"])<br>
</blockquote>
<br></span>
On second thoughts I don't think I understand how the logs are concatenated. I was expecting (15,["Got number: 15") in the original example.<div class="HOEnZb"><div class="h5"><br>
<br>
- Olumide<br>
______________________________<wbr>_________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/beginners</a><br>
</div></div></blockquote></div><br></div>