packed-data 0.1.0.0 → 0.1.0.1
raw patch · 9 files changed
+40/−23 lines, 9 filesdep ~bytestringdep ~deepseqdep ~mtl
Dependency ranges changed: bytestring, deepseq, mtl, template-haskell, time
Files
- README.md +8/−3
- benchmark/Increment.hs +11/−7
- packed-data.cabal +13/−6
- src/Data/Packed/FieldSize.hs +3/−1
- src/Data/Packed/Instances.hs +1/−2
- src/Data/Packed/TH/Case.hs +1/−1
- src/Data/Packed/TH/Read.hs +1/−1
- src/Data/Packed/TH/Skip.hs +1/−1
- src/Data/Packed/TH/Write.hs +1/−1
README.md view
@@ -1,5 +1,8 @@-# `Packed` Haskell+# `packed-data` for Haskell ++[](https://hackage.haskell.org/package/packed-data-0.1.0.0/docs/Data-Packed.html)+ Build, traverse and deserialise packed data in Haskell. ## What is this for?@@ -9,11 +12,11 @@ *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.+`packed-data` 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).+Unlike other implementations of packed-data-support (e.g. [Gibbon](https://drops.dagstuhl.de/entities/document/10.4230/LIPIcs.ECOOP.2017.26)), `packed-data` 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-data` can be used with any version of GHC (as of today, it has been tested GHC 9.2-9.12). 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)). @@ -51,6 +54,8 @@ ``` Take a look at the `benchmark` directory for more examples.++Documentation is available on [Hackage](https://hackage.haskell.org/package/packed-data-0.1.0.0/docs/Data-Packed.html) ## Benchmark
benchmark/Increment.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE CApiFFI #-}+{-# LANGUAGE DeriveGeneric #-} module Increment (benchmark) where @@ -14,6 +15,7 @@ import Data.Void import Foreign import Foreign.C+import GHC.Generics (Generic, Generic1) import Utils import Prelude hiding (concat) @@ -22,11 +24,10 @@ foreign import capi unsafe "benchmark.h build_tree" c_build_tree :: CInt -> IO (Ptr Void) foreign import capi unsafe "benchmark.h free_tree" c_free_tree :: Ptr Void -> IO ()-data Tree1 a = Leaf1 a | Node1 (Tree1 a) (Tree1 a)+data Tree1 a = Leaf1 !a | Node1 !(Tree1 a) !(Tree1 a) deriving (Generic, Generic1) -instance NFData (Tree1 a) where- rnf (Leaf1 a) = a `seq` ()- rnf (Node1 l r) = l `seq` r `seq` ()+instance (NFData a) => NFData (Tree1 a)+instance NFData1 Tree1 $(mkPacked ''Tree1 []) @@ -56,8 +57,11 @@ !nativeTree = buildNativeTree n increment :: Tree1 Int -> Tree1 Int-increment (Leaf1 n) = Leaf1 (n + 1)-increment (Node1 t1 t2) = Node1 (increment t1) (increment t2)+increment (Leaf1 n) = let !res = n + 1 in Leaf1 res+increment (Node1 t1 t2) = Node1 res1 res2+ where+ !res1 = increment t1+ !res2 = increment t2 -- Produces an needsbuilder for a tree alread incremented, and finishes it incrementPackedRunner :: Packed '[Tree1 Int] -> IO (Packed '[Tree1 Int])@@ -82,7 +86,7 @@ buildNativeTree 0 = Leaf1 1 buildNativeTree n = Node1 subTree subTree where- subTree = buildNativeTree (n - 1)+ !subTree = buildNativeTree (n - 1) -- Produces an unpacked tree alread incremented, and packs it repackingIncrementPackedRunner :: Packed '[Tree1 Int] -> IO (Packed '[Tree1 Int])
packed-data.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: packed-data-version: 0.1.0.0+version: 0.1.0.1 description: Build, traverse and deserialise packed data in Haskell category: Data homepage: https://github.com/Arthi-chaud/packed-haskell#readme@@ -16,6 +16,13 @@ license: BSD-3-Clause license-file: LICENSE build-type: Simple+tested-with:+ GHC ==9.2.8+ , GHC ==9.4.8+ , GHC ==9.6.6+ , GHC ==9.8.4+ , GHC ==9.10.1+ , GHC ==9.12.1 extra-source-files: README.md @@ -70,12 +77,12 @@ ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints build-depends: base >=4.7 && <5- , bytestring >=0.12.1.0 && <0.13+ , bytestring >=0.11.0.0 && <0.13 , bytestring-strict-builder >=0.4.5 && <0.5- , deepseq >=1.5.0.0 && <1.6+ , deepseq >=1.4.6.1 && <1.6 , extra >=1.0 && <2.0- , mtl >=2.3.1 && <2.4- , template-haskell >=2.22.0.0 && <2.23+ , mtl >=2.2.2 && <2.4+ , template-haskell >=2.18.0.0 && <=2.24.0.0 default-language: Haskell2010 executable packed-exe@@ -102,7 +109,7 @@ , deepseq , mtl , packed-data- , time ==1.14.*+ , time default-language: Haskell2010 test-suite packed-test
src/Data/Packed/FieldSize.hs view
@@ -63,7 +63,9 @@ {-# INLINE writeWithFieldSize #-} -- | Write a value into a 'Data.Packed.Needs.Needs', along with its 'FieldSize'-writeWithFieldSize :: (Packable a) => a -> NeedsWriter' '[FieldSize, a] r t+--+-- Note: Universal quantifier is nedded for GHC < 9.10, because of ScopedTypeVariables+writeWithFieldSize :: forall a r t. (Packable a) => a -> NeedsWriter' '[FieldSize, a] r t writeWithFieldSize a = write (FieldSize size) N.>> applyNeeds aNeeds where size = fromIntegral (builderLength aBuilder)
src/Data/Packed/Instances.hs view
@@ -7,11 +7,10 @@ -- | This module provides instances of 'Data.Packed.Packable' and 'Data.Packed.Unpackable' for basic types like 'Prelude.List' and 'Prelude.Maybe' module Data.Packed.Instances where -import Data.List (List) import Data.Packed.TH import Data.Packed.Unpackable import Prelude hiding (readList) -$(mkPacked ''List [])+$(mkPacked ''[] []) $(mkPacked ''Maybe []) $(mkPacked ''Either [])
src/Data/Packed/TH/Case.hs view
@@ -10,7 +10,7 @@ import Language.Haskell.TH caseFName :: Name -> Name-caseFName tyName = mkName $ "case" ++ nameBase tyName+caseFName tyName = mkName $ "case" ++ sanitizeConName tyName -- | Generates a function to allow pattern matching a packed data type using the data constructors --
src/Data/Packed/TH/Read.hs view
@@ -11,7 +11,7 @@ import Language.Haskell.TH readFName :: Name -> Name-readFName tyName = mkName $ "read" ++ nameBase tyName+readFName tyName = mkName $ "read" ++ sanitizeConName tyName -- | Generates an function to read (i.e. deserialise) the given data type. --
src/Data/Packed/TH/Skip.hs view
@@ -11,7 +11,7 @@ -- For a data type 'Tree', will generate the function name 'skipTree' skipFName :: Name -> Name-skipFName tyName = mkName $ "skip" ++ nameBase tyName+skipFName tyName = mkName $ "skip" ++ sanitizeConName tyName -- | Generates an function to skip a value of the given type in a 'Data.Packed.Packed' --
src/Data/Packed/TH/Write.hs view
@@ -9,7 +9,7 @@ -- For a data type 'Tree', will generate the function name 'writeTree' writeFName :: Name -> Name-writeFName tyName = mkName $ "write" ++ nameBase tyName+writeFName tyName = mkName $ "write" ++ sanitizeConName tyName -- | Generates a function that serialises and writes a value into a 'Needs' --