construct 0.3.1.2 → 0.3.2
raw patch · 4 files changed
+30/−6 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Construct: manyTill :: (Alternative m, Applicative n, Monoid s) => Format m n s a -> Format m n s () -> Format m n s [a]
+ Construct: sequence :: forall m n s a. (Monad m, AlternativeFail n, Monoid s, Eq a, Show a) => [Format m n s a] -> Format m n s [a]
Files
- CHANGELOG.md +5/−0
- construct.cabal +1/−1
- src/Construct.hs +20/−1
- src/Construct/Internal.hs +4/−4
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for construct +## 0.3.2 -- 2024-12-15++* Added combinators `manyTill` and `sequence`+* Slightly improved documentation+ ## 0.3.1.2 -- 2023-12-19 * Fixed Cabal warnings
construct.cabal view
@@ -1,6 +1,6 @@ cabal-version: >=1.10 name: construct-version: 0.3.1.2+version: 0.3.2 synopsis: Haskell version of the Construct library for easy specification of file formats description: A Haskell version of the <https://construct.readthedocs.io/en/latest/intro.html Construct> library for Python. A
src/Construct.hs view
@@ -1,5 +1,7 @@ {-# LANGUAGE FlexibleContexts, FlexibleInstances, GADTs, RankNTypes, ScopedTypeVariables, TypeOperators #-} +-- | Declarative and symmetrical specification of binary and textual data formats.+ module Construct ( -- * The type@@ -7,7 +9,7 @@ -- * Combinators (Construct.<$), (Construct.*>), (Construct.<*), (Construct.<|>), (<+>), (<?>),- empty, optional, optionWithDefault, pair, deppair, many, some, sepBy, count,+ empty, optional, optionWithDefault, pair, deppair, many, some, manyTill, sepBy, Construct.sequence, count, -- ** Self-referential record support mfix, record, recordWith, -- ** Mapping over a 'Format'@@ -306,9 +308,18 @@ go (Done r _) = pure r go (Partial cont) = Input.anyToken >>= go . cont +-- | Sequence a list of formats into a list format.+sequence :: forall m n s a. (Monad m, AlternativeFail n, Monoid s, Eq a, Show a) => [Format m n s a] -> Format m n s [a]+sequence fs = Format{+ parse = traverse parse fs,+ serialize = \xs-> if length fs == length xs then foldr (liftA2 (<>)) (pure mempty) $ zipWith serialize fs xs+ else failure $ "Expected list of length " <> shows (length fs) (", not " <> show (length xs))}+ count :: (Applicative m, AlternativeFail n, Show a, Monoid s) => Int -> Format m n s a -> Format m n s [a] -- | Repeats the argument format the given number of times. --+-- The property @count n f == Construct.sequence (replicate n f)@ holds.+-- -- >>> testParse (count 4 byte) (ByteString.pack [1,2,3,4,5]) -- Right [([1,2,3,4],"\ENQ")] -- >>> testSerialize (count 4 byte) [1,2,3,4,5]@@ -396,6 +407,14 @@ some f = Format{ parse = Applicative.some (parse f), serialize = maybe (failure "[]") (fmap sconcat . traverse (serialize f)) . nonEmpty}++manyTill :: (Alternative m, Applicative n, Monoid s) => Format m n s a -> Format m n s () -> Format m n s [a]+-- | In the parsing direction, the same as the regular 'Parser.manyTill': parses the item zero or more times until+-- the terminator succeeds. When serializing, makes sure to append the terminator. Beware, for performance reasons+-- the function does /not/ verify that no item's serialization can be parsed via the terminator.+manyTill item end = Format{+ parse = Parser.manyTill (parse item) (parse end),+ serialize = \xs-> liftA2 ((<>) . mconcat) (traverse (serialize item) xs) (serialize end ())} sepBy :: (Alternative m, Applicative n, Monoid s) => Format m n s a -> Format m n s () -> Format m n s [a] -- | Represents any number of values formatted using the first argument, separated by the second format argumewnt in
src/Construct/Internal.hs view
@@ -2,11 +2,11 @@ -- | The central type. The four type parameters are: ----- * @m@ is the type of the parser for the format--- * @n@ is the container type for the serialized form of the value, typically 'Identity' unless something+-- * @m@, type of the parser for the format+-- * @n@, container type for the serialized form of the value, typically 'Identity' unless something -- 'Alternative' is called for.--- * @s@ is the type of the serialized value, typically 'ByteString'--- * @a@ is the type of the value in the program+-- * @s@, type of the serialized value, typically 'ByteString'+-- * @a@, type of the parsed value in memory -- -- The @parse@ and @serialize@ fields can be used to perform the two sides of the conversion between the in-memory and -- serialized form of the value.