[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