array-builder 0.1.4.1 → 0.2.0.0
raw patch · 5 files changed
+185/−27 lines, 5 filesdep +textdep −run-stPVP ok
version bump matches the API change (PVP)
Dependencies added: text
Dependencies removed: run-st
API changes (from Hackage documentation)
+ Data.Builder.Catenable: instance GHC.Base.Functor Data.Builder.Catenable.Builder
+ Data.Builder.Catenable.ShortText: Append :: !Builder -> !Builder -> Builder
+ Data.Builder.Catenable.ShortText: Cons :: !ShortText -> !Builder -> Builder
+ Data.Builder.Catenable.ShortText: Empty :: Builder
+ Data.Builder.Catenable.ShortText: Snoc :: !Builder -> !ShortText -> Builder
+ Data.Builder.Catenable.ShortText: char :: Char -> Builder
+ Data.Builder.Catenable.ShortText: data Builder
+ Data.Builder.Catenable.ShortText: infixl 5 :>
+ Data.Builder.Catenable.ShortText: infixr 5 :<
+ Data.Builder.Catenable.ShortText: instance Data.String.IsString Data.Builder.Catenable.ShortText.Builder
+ Data.Builder.Catenable.ShortText: instance GHC.Base.Monoid Data.Builder.Catenable.ShortText.Builder
+ Data.Builder.Catenable.ShortText: instance GHC.Base.Semigroup Data.Builder.Catenable.ShortText.Builder
+ Data.Builder.Catenable.ShortText: instance GHC.Classes.Eq Data.Builder.Catenable.ShortText.Builder
+ Data.Builder.Catenable.ShortText: instance GHC.Show.Show Data.Builder.Catenable.ShortText.Builder
+ Data.Builder.Catenable.ShortText: int32Dec :: Int32 -> Builder
+ Data.Builder.Catenable.ShortText: int64Dec :: Int64 -> Builder
+ Data.Builder.Catenable.ShortText: length :: Builder -> Int
+ Data.Builder.Catenable.ShortText: pattern (:>) :: Builder -> ShortText -> Builder
+ Data.Builder.Catenable.ShortText: run :: Builder -> Chunks
+ Data.Builder.Catenable.ShortText: shortText :: ShortText -> Builder
+ Data.Builder.Catenable.ShortText: word32Dec :: Word32 -> Builder
+ Data.Builder.Catenable.ShortText: word64Dec :: Word64 -> Builder
+ Data.Builder.Catenable.Text: text :: Text -> Builder
- Data.Builder: Builder :: (forall s. SmallMutableArray# s a -> Int# -> Int# -> Chunks a -> State# s -> (# State# s, SmallMutableArray# s a, Int#, Int#, Chunks a #)) -> Builder a
+ Data.Builder: Builder :: (forall s. () => SmallMutableArray# s a -> Int# -> Int# -> Chunks a -> State# s -> (# State# s, SmallMutableArray# s a, Int#, Int#, Chunks a #)) -> Builder a
- Data.Builder.Catenable.Text: Cons :: !ShortText -> !Builder -> Builder
+ Data.Builder.Catenable.Text: Cons :: !Text -> !Builder -> Builder
- Data.Builder.Catenable.Text: Snoc :: !Builder -> !ShortText -> Builder
+ Data.Builder.Catenable.Text: Snoc :: !Builder -> !Text -> Builder
- Data.Builder.Catenable.Text: pattern (:>) :: Builder -> ShortText -> Builder
+ Data.Builder.Catenable.Text: pattern (:>) :: Builder -> Text -> Builder
Files
- CHANGELOG.md +5/−0
- array-builder.cabal +16/−12
- src/Data/Builder/Catenable.hs +5/−0
- src/Data/Builder/Catenable/ShortText.hs +138/−0
- src/Data/Builder/Catenable/Text.hs +21/−15
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for array-builder +## 0.2.0.0 -- 2025-09-08++* Rename `Data.Builder.Catenable.Text` to `Data.Builder.Catenable.ShortText`+* Add `Data.Builder.Catenable.Text` that uses the `Text` type.+ ## 0.1.4.1 -- 2024-02-01 * Update package metadata.
array-builder.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: array-builder-version: 0.1.4.1+version: 0.2.0.0 synopsis: Builders for arrays description: Builders for arrays. homepage: https://github.com/byteverse/array-builder@@ -12,16 +12,23 @@ copyright: 2019 Andrew Martin category: Data extra-doc-files: CHANGELOG.md+tested-with: GHC ==9.4.8 || ==9.6.3 || ==9.8.1 +common build-settings+ default-language: Haskell2010+ ghc-options: -Wall -Wunused-packages+ library+ import: build-settings exposed-modules: Data.Builder Data.Builder.Catenable Data.Builder.Catenable.Bytes+ Data.Builder.Catenable.ShortText Data.Builder.Catenable.Text Data.Builder.ST - other-modules: Compat+ other-modules: Compat build-depends: , array-chunks >=0.1 && <0.2 , base >=4.12 && <5@@ -30,10 +37,10 @@ , bytestring >=0.11.5 && <0.12 , natural-arithmetic >=0.1.3 && <0.3 , primitive >=0.6.4 && <0.10- , run-st >=0.1 && <0.2 , text-short >=0.1.3 && <0.2+ , text >=2.1 - hs-source-dirs: src+ hs-source-dirs: src if impl(ghc >=8.9) hs-source-dirs: src-post-8.9@@ -41,21 +48,18 @@ else hs-source-dirs: src-pre-8.9 - default-language: Haskell2010- ghc-options: -Wall -O2+ ghc-options: -O2 test-suite test- type: exitcode-stdio-1.0- hs-source-dirs: test- main-is: Main.hs+ import: build-settings+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Main.hs build-depends: , array-builder , base , tasty , tasty-hunit-- ghc-options: -Wall -O2- default-language: Haskell2010 source-repository head type: git
src/Data/Builder/Catenable.hs view
@@ -1,5 +1,8 @@ {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeFamilies #-} {- | Builder with cheap concatenation. Like the builder type from@@ -62,6 +65,8 @@ | Cons a !(Builder a) | Snoc !(Builder a) a | Append !(Builder a) !(Builder a)++deriving stock instance Functor Builder instance Monoid (Builder a) where {-# INLINE mempty #-}
+ src/Data/Builder/Catenable/ShortText.hs view
@@ -0,0 +1,138 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE PatternSynonyms #-}++-- | @Data.Builder.Catenable@ specialized to @ShortText@.+module Data.Builder.Catenable.ShortText+ ( -- * Type+ Builder (..)++ -- * Convenient infix operators+ , pattern (:<)+ , pattern (:>)++ -- * Run+ , run++ -- * Properties+ , length++ -- * Create+ , shortText+ , char+ , word32Dec+ , word64Dec+ , int32Dec+ , int64Dec+ ) where++import Prelude hiding (length)++import Control.Monad.ST (ST, runST)+import Data.ByteString.Short.Internal (ShortByteString (SBS))+import Data.Bytes.Chunks (Chunks (ChunksNil))+import Data.Int (Int32, Int64)+import Data.Primitive (ByteArray (ByteArray))+import Data.String (IsString (fromString))+import Data.Text.Short (ShortText)+import Data.Word (Word32, Word64)++import qualified Arithmetic.Nat as Nat+import qualified Data.Bytes.Builder as BB+import qualified Data.Bytes.Builder.Bounded as Bounded+import qualified Data.Bytes.Builder.Unsafe as BBU+import qualified Data.Bytes.Chunks as Chunks+import qualified Data.Text.Short as TS+import qualified Data.Text.Short.Unsafe as TS++infixr 5 :<+infixl 5 :>++data Builder+ = Empty+ | Cons !ShortText !Builder+ | Snoc !Builder !ShortText+ | Append !Builder !Builder++shortText :: ShortText -> Builder+shortText !t = Cons t Empty++char :: Char -> Builder+char !c = Cons (TS.singleton c) Empty++word32Dec :: Word32 -> Builder+word32Dec !i = Cons (ba2st (Bounded.run Nat.constant (Bounded.word32Dec i))) Empty++word64Dec :: Word64 -> Builder+word64Dec !i = Cons (ba2st (Bounded.run Nat.constant (Bounded.word64Dec i))) Empty++int32Dec :: Int32 -> Builder+int32Dec !i = Cons (ba2st (Bounded.run Nat.constant (Bounded.int32Dec i))) Empty++int64Dec :: Int64 -> Builder+int64Dec !i = Cons (ba2st (Bounded.run Nat.constant (Bounded.int64Dec i))) Empty++-- | Number of Unicode code points in the sequence.+length :: Builder -> Int+length b0 = case b0 of+ Empty -> 0+ Cons x b1 -> TS.length x + length b1+ Snoc b1 x -> TS.length x + length b1+ Append x y -> length x + length y++{- | Note: The choice of appending to the left side of @Empty@ instead+of the right side of arbitrary. Under ordinary use, this difference+cannot be observed by the user.+-}+instance IsString Builder where+ fromString t = Cons (TS.pack t) Empty++instance Monoid Builder where+ {-# INLINE mempty #-}+ mempty = Empty++instance Semigroup Builder where+ {-# INLINE (<>) #-}+ (<>) = Append++{- | Not structural equality. Converts builders to chunks and then+compares the chunks.+-}+instance Eq Builder where+ a == b = run a == run b++instance Show Builder where+ show b = TS.unpack (ba2st (Chunks.concatU (run b)))++ba2st :: ByteArray -> ShortText+{-# INLINE ba2st #-}+ba2st (ByteArray x) = TS.fromShortByteStringUnsafe (SBS x)++pattern (:<) :: ShortText -> Builder -> Builder+pattern (:<) x y = Cons x y++pattern (:>) :: Builder -> ShortText -> Builder+pattern (:>) x y = Snoc x y++{- | The result is chunks, but this is guaranteed to be UTF-8 encoded+text, so if needed, you can flatten out the chunks and convert back+to @ShortText@.+-}+run :: Builder -> Chunks+{-# NOINLINE run #-}+run b = runST $ do+ bldr0 <- BBU.newBuilderState 128+ bldr1 <- pushCatenable bldr0 b+ BBU.reverseCommitsOntoChunks ChunksNil (BBU.closeBuilderState bldr1)++pushCatenable :: BBU.BuilderState s -> Builder -> ST s (BBU.BuilderState s)+pushCatenable !bldr0 b = case b of+ Empty -> pure bldr0+ Cons x b1 -> do+ bldr1 <- BBU.pasteST (BB.shortTextUtf8 x) bldr0+ pushCatenable bldr1 b1+ Snoc b1 x -> do+ bldr1 <- pushCatenable bldr0 b1+ BBU.pasteST (BB.shortTextUtf8 x) bldr1+ Append x y -> do+ bldr1 <- pushCatenable bldr0 x+ pushCatenable bldr1 y
src/Data/Builder/Catenable/Text.hs view
@@ -18,6 +18,7 @@ -- * Create , shortText+ , text , char , word32Dec , word64Dec@@ -33,6 +34,7 @@ import Data.Int (Int32, Int64) import Data.Primitive (ByteArray (ByteArray)) import Data.String (IsString (fromString))+import Data.Text (Text) import Data.Text.Short (ShortText) import Data.Word (Word32, Word64) @@ -41,6 +43,7 @@ import qualified Data.Bytes.Builder.Bounded as Bounded import qualified Data.Bytes.Builder.Unsafe as BBU import qualified Data.Bytes.Chunks as Chunks+import qualified Data.Text as T import qualified Data.Text.Short as TS import qualified Data.Text.Short.Unsafe as TS @@ -49,34 +52,37 @@ data Builder = Empty- | Cons !ShortText !Builder- | Snoc !Builder !ShortText+ | Cons !Text !Builder+ | Snoc !Builder !Text | Append !Builder !Builder shortText :: ShortText -> Builder-shortText !t = Cons t Empty+shortText !t = Cons (TS.toText t) Empty +text :: Text -> Builder+text !t = Cons t Empty+ char :: Char -> Builder-char !c = Cons (TS.singleton c) Empty+char !c = Cons (T.singleton c) Empty word32Dec :: Word32 -> Builder-word32Dec !i = Cons (ba2st (Bounded.run Nat.constant (Bounded.word32Dec i))) Empty+word32Dec !i = Cons (TS.toText (ba2st (Bounded.run Nat.constant (Bounded.word32Dec i)))) Empty word64Dec :: Word64 -> Builder-word64Dec !i = Cons (ba2st (Bounded.run Nat.constant (Bounded.word64Dec i))) Empty+word64Dec !i = Cons (TS.toText (ba2st (Bounded.run Nat.constant (Bounded.word64Dec i)))) Empty int32Dec :: Int32 -> Builder-int32Dec !i = Cons (ba2st (Bounded.run Nat.constant (Bounded.int32Dec i))) Empty+int32Dec !i = Cons (TS.toText (ba2st (Bounded.run Nat.constant (Bounded.int32Dec i)))) Empty int64Dec :: Int64 -> Builder-int64Dec !i = Cons (ba2st (Bounded.run Nat.constant (Bounded.int64Dec i))) Empty+int64Dec !i = Cons (TS.toText (ba2st (Bounded.run Nat.constant (Bounded.int64Dec i)))) Empty -- | Number of Unicode code points in the sequence. length :: Builder -> Int length b0 = case b0 of Empty -> 0- Cons x b1 -> TS.length x + length b1- Snoc b1 x -> TS.length x + length b1+ Cons x b1 -> T.length x + length b1+ Snoc b1 x -> T.length x + length b1 Append x y -> length x + length y {- | Note: The choice of appending to the left side of @Empty@ instead@@ -84,7 +90,7 @@ cannot be observed by the user. -} instance IsString Builder where- fromString t = Cons (TS.pack t) Empty+ fromString t = Cons (T.pack t) Empty instance Monoid Builder where {-# INLINE mempty #-}@@ -107,10 +113,10 @@ {-# INLINE ba2st #-} ba2st (ByteArray x) = TS.fromShortByteStringUnsafe (SBS x) -pattern (:<) :: ShortText -> Builder -> Builder+pattern (:<) :: Text -> Builder -> Builder pattern (:<) x y = Cons x y -pattern (:>) :: Builder -> ShortText -> Builder+pattern (:>) :: Builder -> Text -> Builder pattern (:>) x y = Snoc x y {- | The result is chunks, but this is guaranteed to be UTF-8 encoded@@ -128,11 +134,11 @@ pushCatenable !bldr0 b = case b of Empty -> pure bldr0 Cons x b1 -> do- bldr1 <- BBU.pasteST (BB.shortTextUtf8 x) bldr0+ bldr1 <- BBU.pasteST (BB.textUtf8 x) bldr0 pushCatenable bldr1 b1 Snoc b1 x -> do bldr1 <- pushCatenable bldr0 b1- BBU.pasteST (BB.shortTextUtf8 x) bldr1+ BBU.pasteST (BB.textUtf8 x) bldr1 Append x y -> do bldr1 <- pushCatenable bldr0 x pushCatenable bldr1 y