Skip to content

Instantly share code, notes, and snippets.

@CindyLinz
Created March 2, 2013 14:19
Show Gist options
  • Save CindyLinz/5071195 to your computer and use it in GitHub Desktop.
Save CindyLinz/5071195 to your computer and use it in GitHub Desktop.
Transform ByteString and Integral Num back and forth
positiveDecimalBytesToIntegral :: (Integral num, Num num) => L.ByteString -> num
positiveDecimalBytesToIntegral = collect0
where
collect0 :: (Integral num, Num num) => L.ByteString -> num
collect0 bs = case L.uncons bs of
Just (byte, bs') ->
if 0x30 <= byte && byte <= 0x39
then collect1 (fromIntegral $ byte-0x30) bs'
else collect0 bs'
Nothing -> 0
collect1 :: (Integral num, Num num) => num -> L.ByteString -> num
collect1 acc bs = case L.uncons bs of
Just (byte, bs') ->
if 0x30 <= byte && byte <= 0x39
then collect1 (acc * 10 + fromIntegral (byte-0x30)) bs'
else acc
Nothing -> acc
positiveIntegralToDecimalBytes :: (Integral num, Num num) => num -> L.ByteString
positiveIntegralToDecimalBytes = L.pack . go []
where
go :: (Integral num, Num num) => [Word8] -> num -> [Word8]
go after num
| num <= 9 = (0x30 + fromIntegral num) : after
| otherwise =
let (a, b) = num `divMod` 10
in go ((0x30 + fromIntegral b) : after) a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment