# `Packed` Haskell Build, traverse and deserialise packed data in Haskell. ## What is this for? When components of a system exchange data, each component has to make sure that they send data in a way the recipient will be able to read. A simple example is an API, sending JSON data for the client to parse. This process of decoding the data takes time, especially for big objects like HTML pages. *Packed* data is data serialised into a binary format that is usable as-is, meaning there is no need to parse it to be able to use it. Another perk of such format is that it can be stored in files easily. `packed` allows using packed data type-safely, without explicit pointer arithmetic. ## A portable library Unlike other implementations of packed-data-support (e.g. [Gibbon](https://drops.dagstuhl.de/entities/document/10.4230/LIPIcs.ECOOP.2017.26)), `packed` is a library that does not modify the compiler in any way. It relies solely on already existing libraries (like `ByteString`), Template Haskell and common GHC extensions. This means that, virtually, `packed` can be used with any version of GHC (although, as of today, it has only been tested with GHC 9.10). Its API is inspired by an example from the [Linear Haskell](https://dl.acm.org/doi/10.1145/3158093) paper (code available [here](https://github.com/tweag/linear-types/blob/12bed0d41d599e2697b29c5c4b37990642970e6c/Examples/src/Cursors/PureStorable.hs)). ## Example ```haskell import qualified Data.Packed.Reader as R import Data.Packed data Tree a = Leaf a | Node (Tree a) (Tree a) $(mkPacked ''Tree '[]) -- Compute sum of values in the tree sumPacked :: PackedReader '[Tree Int] r Int sumPacked = caseTree -- Generated by Template Haskell ( R.do -- If Tree is a Leaf !n <- reader R.return n ) ( R.do -- If Tree is a Node !left <- sumPacked !right <- sumPacked let !res = left + right R.return res ) getSum :: Packed '[Tree Int] -> IO Int getSum = runReader sumPacked packTree :: Tree Int -> Packed '[Tree Int] packTree = pack ``` Take a look at the `benchmark` directory for more examples. ## Benchmark To run benchmarks, run the following command: ``` stack bench # Saves the report as CSV stack bench --ba --csv bench.csv # Saves the report, and runs a specific test stach bench --ba '--csv bench.csv sums' ``` Note: Graphs of the benchmark results will be generated in the `graph/` directory when saving the report as CSV.