[Haskell-beginners] Need help understanding the tell function in the Monad Writer example in LYAH

Olumide 50295 at web.de
Mon Feb 6 14:50:25 UTC 2017


I think I get it now. tell() is defined in Control.Monad.Writer as:

     tell   :: w -> m ()
     tell w = writer ((),w)

*also* the result if the do notation is the last expression; and that's 
why the result of the computation will be lost (or disregarded) if 
tell() comes last.

- Olumide

On 03/02/2017 13:54, Francesco Ariis wrote:
>     a Writer do block can be read as a series of function which all have
> a "hidden parameter". This parameter is the pile of log messages.
> So you could as well substitute `tell ...` with
>
>     myTell :: String -> Writer [String] ()
>     myTell s = writer ((), [s])
>
> and then in the do block
>
>     -- ... receiving a list of log messages
>     c <- myTell "something" -- adding mine to the list (and binding
>                             -- a variable)
>     return (a*b) -- c is not being used!
>                  -- but the log message *is* there
>
> You can verify this yourself by adding `logNumber` statement in a do
> block and not using them in the last return statement. There too log
> will appear even if the bound variable is unused.
>
>     multWithLog :: Writer [String] Int
>     multWithLog = do
>  	    a <- logNumber 3
> 	    b <- logNumber 5 -- not used but logged
>         -- equivalent to: logNumber 5 (without b <-)
>  	    return (a)
>
>> Also, I don't understand the paragraph following the example:
>>
>> "It's important that return (a*b) is the last line, because the result of
>> the last line in a do expression is the result of the whole do expression.
>> Had we put tell as the last line, () would have been the result of this do
>> expression. We'd lose the result of the multiplication. However, the log
>> would be the same."
>
> `tell` is really not much different from `myTell`. Let's examine it again:
>
>     myTell :: String -> Writer [String] ()
>     myTell s = writer ((), [s])
>
> See the ()? It means it is *actually* returning something, a ().
> Remember that `return` isn't the same `return` as in some imperative
> languages: it only wraps a value in the monad we are using:
>
>     return 5
>     -- takes `5` and 'lifts' so it is usable inside the Writer
>     -- monad: `(5, [])`
>
> Putting a `tell "something"` after a return statement would overwrite
> that result (and gives us back a () instead).
>
> Did this help?
> My tip for really getting a Monad in your brain is to reimplement it.
> It is a very useful exercise.
> Also learning *not* to use the `do notation` helps too, as having
> operators instead of magic makes things easier to understand.
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>



More information about the Beginners mailing list