<div dir="ltr"><div>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.</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Jul 7, 2019 at 12:13 PM Francesco Ariis <<a href="mailto:fa-ml@ariis.it">fa-ml@ariis.it</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello Terry<br>
<br>
On Sun, Jul 07, 2019 at 11:24:47AM -0400, Terry Phelps wrote:<br>
> I found this code on the net somewhere. It compiles and works properly:<br>
> <br>
> import qualified Data.ByteString as BS<br>
> import Text.Printf (printf)<br>
> toHex :: BS.ByteString -> String<br>
> toHex bytes = do<br>
>   hex <- BS.unpack bytes<br>
>   printf "%02x" hex<br>
> <br>
> I cannot understand the 'do' notation is required, because it seems to be a<br>
> pure function. I guess there's a monad hiding somewhere that my newbie mind<br>
> can't see.<br>
<br>
`toHex` is pure (non IO), but it has an /effect/. In this case, it takes<br>
advantage of the list monad to achieve non-determinism.<br>
<br>
Specifically, since<br>
<br>
    unpack :: ByteString -> [Word8]<br>
<br>
printf (which in our case has signature (`String -> Char`) gets called<br>
on each of those [Word8]. The result will obviously be [Char], which<br>
`String` is an alias of.<br>
<br>
> So, I rewrote the code to remove the 'do stuff':<br>
> <br>
> [...]<br>
> toHex :: BS.ByteString -> String<br>
> toHex bytes = printf "02x" (BS.unpack bytes)<br>
<br>
A do-less version still is /monadic/, hence it will have >>= or >><br>
or similar somewhere. This works:<br>
<br>
    toHex2 :: BS.ByteString -> String<br>
    toHex2 bytes = BS.unpack bytes >>= printf "%02x"<br>
<br>
and follows the reasoning above (feed every every Word8 to<br>
`printf "%02x"`).<br>
<br>
Does this answer your questions?<br>
-F<br>
<br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</blockquote></div>