
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.