Send Beginners mailing list submissions to
        beginners@haskell.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        beginners-requ...@haskell.org

You can reach the person managing the list at
        beginners-ow...@haskell.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1. Re:  Need help understanding the tell function in the Monad
      Writer example in LYAH (Francesco Ariis)
   2.  Bit confused... (mike h)
   3. Re:  Bit confused... (Francesco Ariis)
   4. Re:  Bit confused... (mike h)


----------------------------------------------------------------------

Message: 1
Date: Fri, 3 Feb 2017 14:54:20 +0100
From: Francesco Ariis <fa...@ariis.it>
To: beginners@haskell.org
Subject: Re: [Haskell-beginners] Need help understanding the tell
        function in the Monad Writer example in LYAH
Message-ID: <20170203135420.ga23...@casa.casa>
Content-Type: text/plain; charset=us-ascii

On Fri, Feb 03, 2017 at 11:31:32AM +0000, Olumide wrote:
> Hello List,
> 
> Would someone kindly explain how the tell function interacts with the Writer
> Monad as show below:
> (Example taken from chapter 14 of LYAH
> http://learnyouahaskell.com/for-a-few-monads-more#reader )
> 
> multWithLog :: Writer [String] Int
> multWithLog = do
>       a <- logNumber 3
>       b <- logNumber 5
>       tell ["Gonna multiply these two"]
>       return (a*b)
> 
> Result:
>     ghci> runWriter multWithLog
>     (15,["Got number: 3","Got number: 5","Gonna multiply these two"])
> 
> I know that tell function binds to an argument that is discarded but I don't
> know how its argument "Gonna multiply these two" is concatenated with the
> other the Writer created by logNumber 3 and logNumber 5.
> 
> 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."
> 
> 
> Regards,
> 
> - Olumide

Hello Olumide,
    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.



------------------------------

Message: 2
Date: Fri, 3 Feb 2017 21:47:04 +0000
From: mike h <mike_k_hough...@yahoo.co.uk>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <beginners@haskell.org>
Subject: [Haskell-beginners] Bit confused...
Message-ID: <abfba73e-0586-48b4-8d0c-709c8dc1f...@yahoo.co.uk>
Content-Type: text/plain; charset=utf-8

I have 

----------
import qualified Data.Map as M

type Link a = (a, Int)
data MChain a = Map a   [Link a]  deriving (Show)

-------------------

and want to make a Monoid of MChain. So I have

-------------------
instance Monoid (MChain a) where
   mempty = M.empty 
   mappend = undefined
-------------------

this won’t compile and I need M.empty to be Map a   [Link a] 

The error is
Couldn't match expected type ‘MChain a1’
                 with actual type ‘M.Map k0 a0’
   • In the expression: M.empty :: MChain a
     In an equation for ‘mempty’: mempty = M.empty :: MChain a
     In the instance declaration for ‘Monoid (MChain a)’

This part confuses me "Couldn't match expected type ‘MChain a1 with actual type 
‘M.Map k0 a0’ "


How should I proceed. 

Many thanks

Mike






------------------------------

Message: 3
Date: Fri, 3 Feb 2017 22:59:48 +0100
From: Francesco Ariis <fa...@ariis.it>
To: beginners@haskell.org
Subject: Re: [Haskell-beginners] Bit confused...
Message-ID: <20170203215948.ga11...@casa.casa>
Content-Type: text/plain; charset=utf-8

On Fri, Feb 03, 2017 at 09:47:04PM +0000, mike h wrote:
> I have 
> 
> ----------
> import qualified Data.Map as M
> 
> type Link a = (a, Int)
> data MChain a = Map a   [Link a]  deriving (Show)
> 
> -------------------
> 
> and want to make a Monoid of MChain. So I have
> 
> -------------------
> instance Monoid (MChain a) where
>    mempty = M.empty 
>    mappend = undefined
> -------------------
> 
> this won’t compile and I need M.empty to be Map a   [Link a] 

Hello Mike, I think the error lies in the confusion between
`type` and `data` declaration.

    type Something = Int

but

    data Something = SomeConstructor Int

So I bet you wanted to write

    data MChain a = MChain (M.Map a [Link a]) deriving (Show)

`M.empty` returns a Map.

    λ> :t M.empty
    M.empty :: M.Map k aj

Hence this will work:

    instance Monoid (MChain a) where
       mempty = MChain M.empty
       mappend = undefined

Does this help?





------------------------------

Message: 4
Date: Sat, 4 Feb 2017 08:13:09 +0000
From: mike h <mike_k_hough...@yahoo.co.uk>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <beginners@haskell.org>
Subject: Re: [Haskell-beginners] Bit confused...
Message-ID: <6f289e37-3f47-42f7-ad8d-a8c153c36...@yahoo.co.uk>
Content-Type: text/plain; charset="utf-8"

Yes, that’s exactly what I meant to write!!! :)
Thank you Francesco.

Mike

> On 3 Feb 2017, at 21:59, Francesco Ariis <fa...@ariis.it> wrote:
> 
> On Fri, Feb 03, 2017 at 09:47:04PM +0000, mike h wrote:
>> I have 
>> 
>> ----------
>> import qualified Data.Map as M
>> 
>> type Link a = (a, Int)
>> data MChain a = Map a   [Link a]  deriving (Show)
>> 
>> -------------------
>> 
>> and want to make a Monoid of MChain. So I have
>> 
>> -------------------
>> instance Monoid (MChain a) where
>>   mempty = M.empty 
>>   mappend = undefined
>> -------------------
>> 
>> this won’t compile and I need M.empty to be Map a   [Link a] 
> 
> Hello Mike, I think the error lies in the confusion between
> `type` and `data` declaration.
> 
>    type Something = Int
> 
> but
> 
>    data Something = SomeConstructor Int
> 
> So I bet you wanted to write
> 
>    data MChain a = MChain (M.Map a [Link a]) deriving (Show)
> 
> `M.empty` returns a Map.
> 
>    λ> :t M.empty
>    M.empty :: M.Map k aj
> 
> Hence this will work:
> 
>    instance Monoid (MChain a) where
>       mempty = MChain M.empty
>       mappend = undefined
> 
> Does this help?
> 
> 
> 
> _______________________________________________
> Beginners mailing list
> Beginners@haskell.org <mailto:Beginners@haskell.org>
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners 
> <http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20170204/77e6a737/attachment.html>

------------------------------

Subject: Digest Footer

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


------------------------------

End of Beginners Digest, Vol 104, Issue 2
*****************************************

Reply via email to