I implemented function that reads ByteString and converts it in hex format. E.g. given "AA10" it converts it to [170, 16]
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Internal as BS (w2c)
rHex :: BSL.ByteString -> BSL.ByteString
rHex bs
| BSL.null bs = BSL.empty
| BSL.null rest' = fromHex c1 `BSL.cons` BSL.empty
| otherwise = rChunk c1 c2 `BSL.cons` rHex rest
where (c1, rest') = (BSL.head bs, BSL.tail bs)
(c2, rest) = (BSL.head rest', BSL.tail rest')
rChunk c1 c2 = (fromHex c1) * 16 + fromHex c2
fromHex = fromIntegral . digitToInt . BS.w2c
But than I realized that I need same function but for simple ByteString, not Lazy. The only approach I came to is something like this:
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString as BS
import qualified Data.ByteString.Internal as BS (w2c)
rHex' funcs@(null, empty, cons, head, tail, fromHex) bs
| null bs = empty
| null rest' = fromHex c1 `cons` empty
| otherwise = rChunk c1 c2 `cons` rHex' funcs rest
where (c1, rest') = (head bs, tail bs)
(c2, rest) = (head rest', tail rest')
rChunk c1 c2 = (fromHex c1) * 16 + fromHex c2
fromHex = fromIntegral . digitToInt . BS.w2c
rHexBSL :: BSL.ByteString -> BSL.ByteString
rHexBSL = rHex' (BSL.null, BSL.empty, BSL.cons, BSL.head, BSL.tail, fromHex)
rHexBS :: BS.ByteString -> BS.ByteString
rHexBS = rHex' (BS.null, BS.empty, BS.cons, BS.head, BS.tail, fromHex)
So I pass all needed functions directly in rHex' in functions rHexBSL rHexBS.
Is there more Haskell way to make a common function for Bytestring and Bytestring.Lazy?
Maybe create type class or something?