vector-builder-0.3.7.2/0000755000000000000000000000000013426543540013003 5ustar0000000000000000vector-builder-0.3.7.2/vector-builder.cabal0000644000000000000000000000671513426543540016726 0ustar0000000000000000name: vector-builder version: 0.3.7.2 synopsis: Vector builder description: An API for efficient and convenient construction of vectors. It provides the composable `Builder` abstraction, which has instances of the `Monoid` and `Semigroup` classes. . [Usage] . First you use the `Builder` abstraction to specify the structure of the vector. Then you execute the builder to actually produce the vector. . [Example] . The following code shows how you can efficiently concatenate different datastructures into a single immutable vector: . > >import qualified Data.Vector as A >import qualified VectorBuilder.Builder as B >import qualified VectorBuilder.Vector as C > > >myVector :: A.Vector a -> [a] -> a -> A.Vector a >myVector vector list element = > C.build builder > where > builder = > B.vector vector <> > B.foldable list <> > B.singleton element category: Vector homepage: https://github.com/nikita-volkov/vector-builder bug-reports: https://github.com/nikita-volkov/vector-builder/issues author: Nikita Volkov maintainer: Nikita Volkov copyright: (c) 2016, Nikita Volkov license: MIT license-file: LICENSE build-type: Simple cabal-version: >=1.10 source-repository head type: git location: git://github.com/nikita-volkov/vector-builder.git library hs-source-dirs: library default-extensions: Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples default-language: Haskell2010 exposed-modules: VectorBuilder.Builder VectorBuilder.MVector VectorBuilder.Vector VectorBuilder.MonadPlus VectorBuilder.Alternative other-modules: VectorBuilder.Prelude VectorBuilder.Core.Update VectorBuilder.Core.Builder build-depends: vector >=0.11 && <0.13, semigroups >=0.16 && <0.20, base-prelude <2, base >=4.8 && <5 test-suite tests type: exitcode-stdio-1.0 hs-source-dirs: tests main-is: Main.hs other-modules: Main.Sample default-extensions: Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples default-language: Haskell2010 build-depends: attoparsec >=0.13 && <0.14, QuickCheck >=2.8.1 && <3, quickcheck-instances >=0.3.11 && <0.4, rerebase <2, tasty >=0.12 && <2, tasty-hunit >=0.9 && <0.11, tasty-quickcheck >=0.9 && <0.11, vector-builder vector-builder-0.3.7.2/Setup.hs0000644000000000000000000000005613426543540014440 0ustar0000000000000000import Distribution.Simple main = defaultMain vector-builder-0.3.7.2/LICENSE0000644000000000000000000000204213426543540014006 0ustar0000000000000000Copyright (c) 2016, Nikita Volkov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. vector-builder-0.3.7.2/tests/0000755000000000000000000000000013426543540014145 5ustar0000000000000000vector-builder-0.3.7.2/tests/Main.hs0000644000000000000000000000362513426543540015373 0ustar0000000000000000module Main where import Prelude import Test.Tasty import Test.Tasty.Runners import Test.Tasty.HUnit import Test.Tasty.QuickCheck import qualified VectorBuilder.Builder as A import qualified VectorBuilder.Vector as B import qualified VectorBuilder.Alternative as F import qualified VectorBuilder.MonadPlus as H import qualified Main.Sample as C import qualified Data.Attoparsec.Text as D import qualified Data.Vector as E import qualified Data.Text as G main = defaultMain $ testGroup "All tests" [ testProperty "samples" $ \(samples :: [C.Sample Int]) -> foldMap C.toVector samples === B.build (foldMap C.toBuilder samples) , testCase "Alternative.some" $ assertEqual "" (Right (E.fromList "1234")) (D.parseOnly (F.some D.anyChar) "1234") , testCase "Alternative.some on empty" $ assertEqual "" (Left "not enough input") (D.parseOnly (F.some D.anyChar :: D.Parser (Vector Char)) "") , testProperty "mconcat" $ \(samples :: [C.Sample Int]) -> foldMap C.toVector samples === B.build (mconcat (map C.toBuilder samples)) , testProperty "foldable" $ \(elements :: [Int]) -> E.fromList elements === B.build (A.foldable elements) , testGroup "MonadPlus" [ testProperty "many" $ \(elements :: [Char]) -> Right (E.fromList elements) === D.parseOnly (H.many D.anyChar) (fromString elements) , testProperty "many1" $ \(elements :: [Char]) -> (if null elements then Left "not enough input" else Right (E.fromList elements)) === D.parseOnly (H.many1 D.anyChar) (fromString elements) , testProperty "sepBy1" $ \(elements :: [Char]) -> (if null elements then Left "not enough input" else Right (E.fromList elements)) === D.parseOnly (H.sepBy1 D.anyChar (D.char ',')) (G.intersperse ',' (fromString elements)) ] ] vector-builder-0.3.7.2/tests/Main/0000755000000000000000000000000013426543540015031 5ustar0000000000000000vector-builder-0.3.7.2/tests/Main/Sample.hs0000644000000000000000000000164013426543540016607 0ustar0000000000000000module Main.Sample where import Prelude import Test.QuickCheck.Instances import qualified VectorBuilder.Builder as A import qualified Data.Vector as B import qualified Test.Tasty.QuickCheck as C data Sample a = Empty | Singleton a | Vector (Vector a) | List [a] deriving (Show) toBuilder :: Sample a -> A.Builder a toBuilder = \case Empty -> A.empty Singleton a -> A.singleton a Vector a -> A.vector a List a -> A.foldable a toVector :: Sample a -> Vector a toVector = \case Empty -> B.empty Singleton a -> B.singleton a Vector a -> a List a -> B.fromList a instance C.Arbitrary a => C.Arbitrary (Sample a) where arbitrary = do constructorIndex <- C.choose (0 :: Int, 3) case constructorIndex of 0 -> return Empty 1 -> C.arbitrary >>= return . Singleton 2 -> C.arbitrary >>= return . Vector 3 -> C.arbitrary >>= return . List vector-builder-0.3.7.2/library/0000755000000000000000000000000013426543540014447 5ustar0000000000000000vector-builder-0.3.7.2/library/VectorBuilder/0000755000000000000000000000000013426543540017220 5ustar0000000000000000vector-builder-0.3.7.2/library/VectorBuilder/Prelude.hs0000644000000000000000000000033613426543540021156 0ustar0000000000000000module VectorBuilder.Prelude ( module Exports, strict, ) where import BasePrelude as Exports hiding ((<>)) import Data.Semigroup as Exports (Semigroup(..)) {-# INLINE strict #-} strict :: a -> a strict a = seq a a vector-builder-0.3.7.2/library/VectorBuilder/Builder.hs0000644000000000000000000000020113426543540021133 0ustar0000000000000000module VectorBuilder.Builder ( Builder, empty, singleton, vector, foldable, ) where import VectorBuilder.Core.Builder vector-builder-0.3.7.2/library/VectorBuilder/MVector.hs0000644000000000000000000000112713426543540021134 0ustar0000000000000000-- | -- Extensions to the standard mutable Vector API. module VectorBuilder.MVector where import VectorBuilder.Prelude import Data.Vector.Generic.Mutable import qualified VectorBuilder.Core.Builder as A import qualified VectorBuilder.Core.Update as C -- | -- Construct a mutable vector from a builder. -- -- Supports all kinds of vectors: boxed, unboxed, primitive, storable. {-# INLINABLE build #-} build :: MVector vector element => A.Builder element -> ST s (vector s element) build (A.Builder size (C.Update update)) = do vector <- unsafeNew size update vector 0 return vector vector-builder-0.3.7.2/library/VectorBuilder/Vector.hs0000644000000000000000000000101213426543540021010 0ustar0000000000000000-- | -- Extensions to the standard immutable Vector API. module VectorBuilder.Vector where import VectorBuilder.Prelude import Data.Vector.Generic import qualified VectorBuilder.Core.Builder as A import qualified VectorBuilder.MVector as B -- | -- Construct an immutable vector from a builder. -- -- Supports all kinds of vectors: boxed, unboxed, primitive, storable. {-# INLINE build #-} build :: Vector vector element => A.Builder element -> vector element build builder = runST (B.build builder >>= unsafeFreeze) vector-builder-0.3.7.2/library/VectorBuilder/Alternative.hs0000644000000000000000000000161613426543540022036 0ustar0000000000000000{-| Alternative utilities. For instance, they can be applied with parsing libraries. -} module VectorBuilder.Alternative where import VectorBuilder.Prelude hiding (many, some) import Data.Vector (Vector) import qualified VectorBuilder.Builder as A import qualified VectorBuilder.Vector as B import qualified Data.Vector.Generic as C {-# INLINABLE many #-} many :: (Alternative m, C.Vector vector a) => m a -> m (vector a) many = fmap B.build . manyBuilder {-# INLINABLE manyBuilder #-} manyBuilder :: Alternative m => m a -> m (A.Builder a) manyBuilder m = let loop = ((<>) <$> A.singleton <$> m <*> loop) <|> pure mempty in loop {-# INLINABLE some #-} some :: (Alternative m, C.Vector vector a) => m a -> m (vector a) some m = B.build <$> someBuilder m {-# INLINABLE someBuilder #-} someBuilder :: Alternative m => m a -> m (A.Builder a) someBuilder m = (<>) <$> A.singleton <$> m <*> manyBuilder m vector-builder-0.3.7.2/library/VectorBuilder/MonadPlus.hs0000644000000000000000000000311713426543540021460 0ustar0000000000000000{-| MonadPlus utilities. For instance, they can be applied with parsing libraries. -} module VectorBuilder.MonadPlus where import VectorBuilder.Prelude import Data.Vector (Vector) import qualified VectorBuilder.Builder as A import qualified VectorBuilder.Vector as B import qualified Data.Vector.Generic as C {-# INLINABLE many #-} many :: (MonadPlus m, C.Vector vector element) => m element -> m (vector element) many m = liftM B.build (manyBuilder m) {-# INLINABLE manyBuilder #-} manyBuilder :: (MonadPlus m) => m element -> m (A.Builder element) manyBuilder m = loop mempty where loop !builder = mplus (do !element <- m loop (builder <> A.singleton element)) (return builder) {-# INLINABLE many1 #-} many1 :: (MonadPlus m, C.Vector vector element) => m element -> m (vector element) many1 m = do firstElement <- m builder <- manyBuilder m return (B.build (A.singleton firstElement <> builder)) {-# INLINABLE sepBy #-} sepBy :: (MonadPlus m, C.Vector vector element) => m element -> m separator -> m (vector element) sepBy elementM separatorM = mplus (sepBy1 elementM separatorM) (return C.empty) {-# INLINABLE sepBy1 #-} sepBy1 :: (MonadPlus m, C.Vector vector element) => m element -> m separator -> m (vector element) sepBy1 elementM separatorM = do firstElement <- elementM builder <- loop (A.singleton firstElement) return (B.build builder) where loop builder = mplus (do separatorM !element <- elementM loop (builder <> A.singleton element)) (return builder) vector-builder-0.3.7.2/library/VectorBuilder/Core/0000755000000000000000000000000013426543540020110 5ustar0000000000000000vector-builder-0.3.7.2/library/VectorBuilder/Core/Builder.hs0000644000000000000000000000522113426543540022032 0ustar0000000000000000module VectorBuilder.Core.Builder where import VectorBuilder.Prelude hiding (empty, concat) import qualified VectorBuilder.Core.Update as A import qualified Data.Vector.Generic as B import qualified Data.Vector.Generic.Mutable as C -- | -- An abstraction over the size of a vector for the process of its construction. -- -- It postpones the actual construction of a vector until the execution of the builder. data Builder element = Builder !Int !(A.Update element) -- * Initialisation -- | -- Empty builder. {-# INLINE empty #-} empty :: Builder element empty = Builder 0 A.empty -- | -- Builder of a single element. {-# INLINE singleton #-} singleton :: element -> Builder element singleton element = Builder 1 (A.write element) -- | -- Builder from an immutable vector of elements. -- -- Supports all kinds of vectors: boxed, unboxed, primitive, storable. {-# INLINE vector #-} vector :: B.Vector vector element => vector element -> Builder element vector vector = Builder (B.length vector) (A.writeMany vector) {-# INLINE foldable #-} foldable :: Foldable foldable => foldable element -> Builder element foldable foldable = Builder (length foldable) (A.writeFoldable foldable) -- * Updates {-# INLINE snoc #-} snoc :: element -> Builder element -> Builder element snoc element (Builder size update) = Builder (succ size) (A.prepend size update (A.write element)) {-# INLINE cons #-} cons :: element -> Builder element -> Builder element cons element (Builder size update) = Builder (succ size) (A.prepend 1 (A.write element) update) {-# INLINE prepend #-} prepend :: Builder element -> Builder element -> Builder element prepend (Builder leftSize leftUpdate) (Builder rightSize rightUpdate) = Builder (leftSize + rightSize) (A.prepend leftSize leftUpdate rightUpdate) {-# INLINE append #-} append :: Builder element -> Builder element -> Builder element append = flip prepend {-# INLINE concat #-} concat :: Foldable foldable => foldable (Builder element) -> Builder element concat builders = Builder (let step size (Builder builderSize _) = size + builderSize in foldl' step 0 builders) (A.Update (\mVector offset -> foldM_ (\index (Builder size (A.Update st)) -> st mVector index $> index + size) offset builders)) -- * Instances -- | -- Provides support for /O(1)/ concatenation. instance Semigroup (Builder element) where {-# INLINE (<>) #-} (<>) = prepend sconcat = concat -- | -- Provides support for /O(1)/ concatenation. instance Monoid (Builder element) where {-# INLINE mempty #-} mempty = empty {-# INLINE mappend #-} mappend = (<>) {-# INLINE mconcat #-} mconcat = concat vector-builder-0.3.7.2/library/VectorBuilder/Core/Update.hs0000644000000000000000000000234313426543540021670 0ustar0000000000000000module VectorBuilder.Core.Update where import VectorBuilder.Prelude import qualified Data.Vector.Generic.Mutable as A import qualified Data.Vector.Generic as B newtype Update element = Update (forall s vector. A.MVector vector element => vector s element -> Int -> ST s ()) {-# INLINE write #-} write :: element -> Update element write element = Update (\mVector offset -> A.unsafeWrite mVector offset element) {-# INLINE writeMany #-} writeMany :: B.Vector vector element => vector element -> Update element writeMany appendedVector = Update (\mVector offset -> B.ifoldM' (\_ index element -> A.unsafeWrite mVector (strict (offset + index)) element) () appendedVector) {-# INLINE prepend #-} prepend :: Int -> Update element -> Update element -> Update element prepend size (Update leftST) (Update rightST) = Update (\mVector offset -> leftST mVector offset >> rightST mVector (strict (size + offset))) {-# INLINE empty #-} empty :: Update element empty = Update (\_ _ -> pure ()) {-# INLINE writeFoldable #-} writeFoldable :: Foldable foldable => foldable element -> Update element writeFoldable foldable = Update (\mVector offset -> foldM_ (\ index element -> A.unsafeWrite mVector index element $> succ index) offset foldable)