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.  Question about code I found (Terry Phelps)
   2. Re:  Question about code I found (Francesco Ariis)
   3. Re:  Question about code I found (Terry Phelps)
   4. Re:  Question about code I found (KC)


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

Message: 1
Date: Sun, 7 Jul 2019 11:24:47 -0400
From: Terry Phelps <tgphelp...@gmail.com>
To: beginners@haskell.org
Subject: [Haskell-beginners] Question about code I found
Message-ID:
        <CAMUfR_vuy1Kf=d5pdk5gqn8bp88zwolhyt3gevtog8zymwg...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

I found this code on the net somewhere. It compiles and works properly:

import qualified Data.ByteString as BS
import Text.Printf (printf)
toHex :: BS.ByteString -> String
toHex bytes = do
  hex <- BS.unpack bytes
  printf "%02x" hex

I cannot understand the 'do' notation is required, because it seems to be a
pure function. I guess there's a monad hiding somewhere that my newbie mind
can't see.

So, I rewrote the code to remove the 'do stuff':

-- BAD
import qualified Data.ByteString as BS
import Text.Printf (printf)
toHex :: BS.ByteString -> String
toHex bytes = printf "02x" (BS.unpack bytes)

WRONG. Ghci says:

xx2.hs:5:15: error:
    • No instance for (Text.Printf.IsChar GHC.Word.Word8)
        arising from a use of ‘printf’
    • In the expression: printf "02x" (BS.unpack bytes)
      In an equation for ‘toHex’:
          toHex bytes = printf "02x" (BS.unpack bytes)
  |
5 | toHex bytes = printf "02x" (BS.unpack bytes)
  |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Can someone please explain to me:
1. Why does this simple-looking code to convert a bytestring to a string of
hex characters require 'do' or equivalent code?
2. What is the specific problem with my version of the code. The error
message doesn't mean much to me yet.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20190707/14bf0fbb/attachment-0001.html>

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

Message: 2
Date: Sun, 7 Jul 2019 18:12:45 +0200
From: Francesco Ariis <fa...@ariis.it>
To: beginners@haskell.org
Subject: Re: [Haskell-beginners] Question about code I found
Message-ID: <20190707161245.4pxyi66a5xwr3...@x60s.casa>
Content-Type: text/plain; charset=us-ascii

Hello Terry

On Sun, Jul 07, 2019 at 11:24:47AM -0400, Terry Phelps wrote:
> I found this code on the net somewhere. It compiles and works properly:
> 
> import qualified Data.ByteString as BS
> import Text.Printf (printf)
> toHex :: BS.ByteString -> String
> toHex bytes = do
>   hex <- BS.unpack bytes
>   printf "%02x" hex
> 
> I cannot understand the 'do' notation is required, because it seems to be a
> pure function. I guess there's a monad hiding somewhere that my newbie mind
> can't see.

`toHex` is pure (non IO), but it has an /effect/. In this case, it takes
advantage of the list monad to achieve non-determinism.

Specifically, since

    unpack :: ByteString -> [Word8]

printf (which in our case has signature (`String -> Char`) gets called
on each of those [Word8]. The result will obviously be [Char], which
`String` is an alias of.

> So, I rewrote the code to remove the 'do stuff':
> 
> [...]
> toHex :: BS.ByteString -> String
> toHex bytes = printf "02x" (BS.unpack bytes)

A do-less version still is /monadic/, hence it will have >>= or >>
or similar somewhere. This works:

    toHex2 :: BS.ByteString -> String
    toHex2 bytes = BS.unpack bytes >>= printf "%02x"

and follows the reasoning above (feed every every Word8 to
`printf "%02x"`).

Does this answer your questions?
-F



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

Message: 3
Date: Sun, 7 Jul 2019 12:47:19 -0400
From: Terry Phelps <tgphelp...@gmail.com>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <beginners@haskell.org>
Subject: Re: [Haskell-beginners] Question about code I found
Message-ID:
        <camufr_tw8odvdd1hmdafbnf_fxv+x-maktzxnh5xql4gkgs...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

I have written enough code in the IO monad to fairly well understand how
the 'do' and 'bind' forms work. But I've never seen monadic code that was
NOT in the IO monad. Your explanation tells me where to go do more study.
Thank you.If I go read the definition of bind in the List monad, it will
probably become clear. In the original code, the List monad is completely
invisible to my untrained eye, and I was confused.


On Sun, Jul 7, 2019 at 12:13 PM Francesco Ariis <fa...@ariis.it> wrote:

> Hello Terry
>
> On Sun, Jul 07, 2019 at 11:24:47AM -0400, Terry Phelps wrote:
> > I found this code on the net somewhere. It compiles and works properly:
> >
> > import qualified Data.ByteString as BS
> > import Text.Printf (printf)
> > toHex :: BS.ByteString -> String
> > toHex bytes = do
> >   hex <- BS.unpack bytes
> >   printf "%02x" hex
> >
> > I cannot understand the 'do' notation is required, because it seems to
> be a
> > pure function. I guess there's a monad hiding somewhere that my newbie
> mind
> > can't see.
>
> `toHex` is pure (non IO), but it has an /effect/. In this case, it takes
> advantage of the list monad to achieve non-determinism.
>
> Specifically, since
>
>     unpack :: ByteString -> [Word8]
>
> printf (which in our case has signature (`String -> Char`) gets called
> on each of those [Word8]. The result will obviously be [Char], which
> `String` is an alias of.
>
> > So, I rewrote the code to remove the 'do stuff':
> >
> > [...]
> > toHex :: BS.ByteString -> String
> > toHex bytes = printf "02x" (BS.unpack bytes)
>
> A do-less version still is /monadic/, hence it will have >>= or >>
> or similar somewhere. This works:
>
>     toHex2 :: BS.ByteString -> String
>     toHex2 bytes = BS.unpack bytes >>= printf "%02x"
>
> and follows the reasoning above (feed every every Word8 to
> `printf "%02x"`).
>
> Does this answer your questions?
> -F
>
> _______________________________________________
> Beginners mailing list
> Beginners@haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20190707/0136b91a/attachment-0001.html>

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

Message: 4
Date: Sun, 7 Jul 2019 11:16:23 -0700
From: KC <kc1...@gmail.com>
To: Haskell Beginners <beginners@haskell.org>
Subject: Re: [Haskell-beginners] Question about code I found
Message-ID:
        <CAMLKXynf8Y=wznfoswtsdwiractogtdfg3tbr6cfc0ba0xr...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

It's more correct to say the
List Monad
Is a
Monad instance who is a List

But people look at you funny
In my case
Funnier than usual
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20190707/6899821e/attachment-0001.html>

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

Subject: Digest Footer

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


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

End of Beginners Digest, Vol 133, Issue 1
*****************************************

Reply via email to