
On 27/01/2017 08:34, Theodore Lief Gannon wrote:
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.
First, let's desugar that do notation to the equivalent bind chain:
multWithLog = logNumber 3 >>= \a -> logNumber 5 >>= \b -> return (a*b)
Evaluate the logNumber and return calls to normal form from their definitions, also considering the monoid definitions of (++) and mempty for lists:
multWithLog = Writer (3, ["Got number: 3"]) >>= \a -> Writer (5, ["Got number: 5"]) >>= \b -> Writer (a*b, [])
Now, refer to the definition of (>>=) for Writer (as shown in LYAH):
(Writer (x, v)) >>= f = let (Writer (y, v')) = f x in Writer (y, v `mappend` v')
Thank you for your explanation. The substitutions helped a lot even though I wasn't able to follow the equational reasoning. The expansion gave me enough starting information to figure out what's going on by starting from the innermost bind. BTW, I thought the definition of (>>=) was supposed to come from Control.Monad.Writer. Regards, - Olumide