Skip to content

Instantly share code, notes, and snippets.

@HeinrichApfelmus
Last active March 21, 2020 13:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HeinrichApfelmus/4968229 to your computer and use it in GitHub Desktop.
Save HeinrichApfelmus/4968229 to your computer and use it in GitHub Desktop.
Parsing a random-access format into a pure data structure. Parsing will be lazy: parts of the data structure will be parsed on demand.
import Data.Word
import qualified Data.ByteString as B
type ByteString = B.ByteString
data Tree = Leaf [Word8] | Branch Tree Tree deriving (Eq,Show)
parse :: ByteString -> Tree
parse xs = case view xs of
Cons 0 xs -> case view xs of
Cons length xs -> Leaf . B.unpack $ B.take (fromIntegral . toInteger $ length) xs
Cons 1 xs -> case view xs of
Cons length xs -> let (a,b) = B.splitAt (fromIntegral . toInteger $ length) xs in
Branch (parse a) (parse b)
data View = Nil | Cons Word8 ByteString
view :: ByteString -> View
view xs
| B.null xs = Nil
| otherwise = Cons (B.head xs) (B.tail xs)
serialize :: Tree -> ByteString
serialize (Branch x y) =
1 `B.cons` (length `B.cons` (sx `B.append` serialize y))
where
sx = serialize x
length = fromIntegral . toInteger $ B.length sx
serialize (Leaf ws) =
0 `B.cons` (length `B.cons` w)
where
w = B.pack ws
length = fromIntegral . toInteger $ B.length w
exampleTree = Branch (Leaf [1,2,3]) (Branch (Leaf []) (Leaf [4,5]))
-- try
-- > parse $ serialize exampleTree
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment