1

Looking at some Writer monad examples, in the one from Learn You a Haskell I don't see where the use of * multiplication operator in the last line expression is overloaded to work with the with the Writer objects produced by the logNumber functions:

import Control.Monad.Writer logNumber :: Int -> Writer [String] Int logNumber x = Writer (x, ["Got number: " ++ show x]) multWithLog :: Writer [String] Int multWithLog = do a <- logNumber 3 b <- logNumber 5 return (a*b) 

1 Answer 1

6

There seems to be some misunderstanding here. In your example code:

import Control.Monad.Writer logNumber :: Int -> Writer [String] Int logNumber x = Writer (x, ["Got number: " ++ show x]) multWithLog :: Writer [String] Int multWithLog = do a <- logNumber 3 b <- logNumber 5 return (a*b) 

the values a and b are not Writer values. Their type is simply Int, and of course you can multiply 2 Ints. Therefore a*b is an Int too - note the use of return on it in the last line, which is needed here precisely in order to "lift" the "ordinary value" a*b of type Int to a "monadic value" of type Writer [String] Int.

logNumber 3 is certainly a monadic value (of type Writer [String] Int), but the <- syntactic sugar of do notation "extracts" the underlying value out of it, and gives it a name - here a. More precisely, the do block above desugars to:

multWithLog = logNumber 3 >>= \a -> logNumber 5 >>= \b -> return (a*b) 

where the lambda expressions have type Int -> Writer [String] Int (the arguments a and b being the Ints in question), which due to the type of >>= produces an expression of type Writer [String] Int overall.

Sign up to request clarification or add additional context in comments.

4 Comments

Ah; yes - I was overlooking the deconstruction of the writer tuple in the >>= operator definition. The magic of hidden monadic computations. Thanks.
Yes, indeed - but note that none of my above argument relies on the fact that Writer happens to extract a value from a tuple in the >>= definition. We need know nothing about Writer at all, other than that Writer [String] is a monad, and everything I said in my answer would still be true, and mean that a and b in the code example have type Int.
Indeed - interesting. But it does seem that the monad instance for Writer is needed to propagate the associated string(s).
yes indeed, what Writer [String] does as its "side effect" is append a string to a growing collection. (And it works the same way for any monoid m in place of [String].)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.