[Haskell-beginners] Question about code I found

Francesco Ariis fa-ml at ariis.it
Sun Jul 7 16:12:45 UTC 2019


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



More information about the Beginners mailing list