vector-builder-0.3.8.5/0000755000000000000000000000000007346545000013004 5ustar0000000000000000vector-builder-0.3.8.5/LICENSE0000644000000000000000000000204207346545000014007 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.8.5/library/VectorBuilder/0000755000000000000000000000000007346545000017221 5ustar0000000000000000vector-builder-0.3.8.5/library/VectorBuilder/Alternative.hs0000644000000000000000000000157607346545000022044 0ustar0000000000000000-- | -- Alternative utilities. -- For instance, they can be applied with parsing libraries. module VectorBuilder.Alternative where import qualified Data.Vector.Generic as C import qualified VectorBuilder.Builder as A import VectorBuilder.Prelude hiding (many, some) import qualified VectorBuilder.Vector as B {-# INLINEABLE many #-} many :: (Alternative m, C.Vector vector a) => m a -> m (vector a) many = fmap B.build . manyBuilder {-# INLINEABLE manyBuilder #-} manyBuilder :: (Alternative m) => m a -> m (A.Builder a) manyBuilder m = let loop = ((<>) <$> A.singleton <$> m <*> loop) <|> pure mempty in loop {-# INLINEABLE some #-} some :: (Alternative m, C.Vector vector a) => m a -> m (vector a) some m = B.build <$> someBuilder m {-# INLINEABLE someBuilder #-} someBuilder :: (Alternative m) => m a -> m (A.Builder a) someBuilder m = (<>) <$> A.singleton <$> m <*> manyBuilder m vector-builder-0.3.8.5/library/VectorBuilder/Builder.hs0000644000000000000000000000022507346545000021142 0ustar0000000000000000module VectorBuilder.Builder ( Builder, empty, singleton, size, vector, foldable, ) where import VectorBuilder.Core.Builder vector-builder-0.3.8.5/library/VectorBuilder/Core/0000755000000000000000000000000007346545000020111 5ustar0000000000000000vector-builder-0.3.8.5/library/VectorBuilder/Core/Builder.hs0000644000000000000000000000545507346545000022044 0ustar0000000000000000module VectorBuilder.Core.Builder where import qualified Data.Vector.Generic as B import qualified VectorBuilder.Core.Update as A import VectorBuilder.Prelude hiding (concat, empty) -- | -- 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) -- | -- Gets the size of a Builder. {-# INLINE size #-} size :: Builder element -> Int size (Builder s _) = s -- * 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.8.5/library/VectorBuilder/Core/Update.hs0000644000000000000000000000234707346545000021675 0ustar0000000000000000module VectorBuilder.Core.Update where import qualified Data.Vector.Generic as B import qualified Data.Vector.Generic.Mutable as A import VectorBuilder.Prelude 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) vector-builder-0.3.8.5/library/VectorBuilder/MVector.hs0000644000000000000000000000113007346545000021127 0ustar0000000000000000-- | -- Extensions to the standard mutable Vector API. module VectorBuilder.MVector where import Data.Vector.Generic.Mutable import qualified VectorBuilder.Core.Builder as A import qualified VectorBuilder.Core.Update as C import VectorBuilder.Prelude -- | -- Construct a mutable vector from a builder. -- -- Supports all kinds of vectors: boxed, unboxed, primitive, storable. {-# INLINEABLE 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.8.5/library/VectorBuilder/MonadPlus.hs0000644000000000000000000000313107346545000021455 0ustar0000000000000000-- | -- MonadPlus utilities. -- For instance, they can be applied with parsing libraries. module VectorBuilder.MonadPlus where import qualified Data.Vector.Generic as C import qualified VectorBuilder.Builder as A import VectorBuilder.Prelude import qualified VectorBuilder.Vector as B {-# INLINEABLE many #-} many :: (MonadPlus m, C.Vector vector element) => m element -> m (vector element) many m = liftM B.build (manyBuilder m) {-# INLINEABLE 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) {-# INLINEABLE 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)) {-# INLINEABLE 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) {-# INLINEABLE 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.8.5/library/VectorBuilder/Prelude.hs0000644000000000000000000000562407346545000021164 0ustar0000000000000000module VectorBuilder.Prelude ( module Exports, strict, ) where import Control.Applicative as Exports import Control.Arrow as Exports hiding (first, second) import Control.Category as Exports import Control.Concurrent as Exports import Control.Exception as Exports import Control.Monad as Exports hiding (fail, forM, forM_, mapM, mapM_, msum, sequence, sequence_) import Control.Monad.Fail as Exports import Control.Monad.Fix as Exports hiding (fix) import Control.Monad.IO.Class as Exports import Control.Monad.ST as Exports import Data.Bifunctor as Exports import Data.Bits as Exports import Data.Bool as Exports import Data.Char as Exports import Data.Coerce as Exports import Data.Complex as Exports import Data.Data as Exports import Data.Dynamic as Exports import Data.Either as Exports import Data.Fixed as Exports import Data.Foldable as Exports hiding (toList) import Data.Function as Exports hiding (id, (.)) import Data.Functor as Exports hiding (unzip) import Data.Functor.Compose as Exports import Data.IORef as Exports import Data.Int as Exports import Data.Ix as Exports import Data.List as Exports hiding (all, and, any, concat, concatMap, elem, find, foldl, foldl', foldl1, foldr, foldr1, isSubsequenceOf, mapAccumL, mapAccumR, maximum, maximumBy, minimum, minimumBy, notElem, or, product, sortOn, sum, uncons) import Data.List.NonEmpty as Exports (NonEmpty (..)) import Data.Maybe as Exports import Data.Monoid as Exports hiding (Alt) import Data.Ord as Exports import Data.Proxy as Exports import Data.Ratio as Exports import Data.STRef as Exports import Data.Semigroup as Exports (Semigroup (..)) import Data.String as Exports import Data.Traversable as Exports import Data.Tuple as Exports import Data.Unique as Exports import Data.Version as Exports import Data.Void as Exports import Data.Word as Exports import Debug.Trace as Exports import Foreign.ForeignPtr as Exports import Foreign.Ptr as Exports import Foreign.StablePtr as Exports import Foreign.Storable as Exports import GHC.Conc as Exports hiding (orElse, threadWaitRead, threadWaitReadSTM, threadWaitWrite, threadWaitWriteSTM, withMVar) import GHC.Exts as Exports (IsList (..), groupWith, inline, lazy, sortWith) import GHC.Generics as Exports (Generic) import GHC.IO.Exception as Exports import Numeric as Exports import System.Environment as Exports import System.Exit as Exports import System.IO import System.IO.Error as Exports import System.IO.Unsafe as Exports import System.Mem as Exports import System.Mem.StableName as Exports import System.Timeout as Exports import Text.Printf as Exports (hPrintf, printf) import Text.Read as Exports (Read (..), readEither, readMaybe) import Unsafe.Coerce as Exports import Prelude as Exports hiding (all, and, any, concat, concatMap, elem, fail, foldl, foldl1, foldr, foldr1, id, mapM, mapM_, maximum, minimum, notElem, or, product, sequence, sequence_, sum, (.)) {-# INLINE strict #-} strict :: a -> a strict a = seq a a vector-builder-0.3.8.5/library/VectorBuilder/Vector.hs0000644000000000000000000000101207346545000021011 0ustar0000000000000000-- | -- Extensions to the standard immutable Vector API. module VectorBuilder.Vector where import Data.Vector.Generic import qualified VectorBuilder.Core.Builder as A import qualified VectorBuilder.MVector as B import VectorBuilder.Prelude -- | -- 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.8.5/tests/0000755000000000000000000000000007346545000014146 5ustar0000000000000000vector-builder-0.3.8.5/tests/Main.hs0000644000000000000000000000415007346545000015366 0ustar0000000000000000module Main where import qualified Data.Attoparsec.Text as D import qualified Data.Text as G import qualified Data.Vector as E import qualified Main.Sample as C import Test.Tasty import Test.Tasty.HUnit import Test.Tasty.QuickCheck import qualified VectorBuilder.Alternative as F import qualified VectorBuilder.Builder as A import qualified VectorBuilder.MonadPlus as H import qualified VectorBuilder.Vector as B import Prelude main :: IO () 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.8.5/tests/Main/0000755000000000000000000000000007346545000015032 5ustar0000000000000000vector-builder-0.3.8.5/tests/Main/Sample.hs0000644000000000000000000000167507346545000016620 0ustar0000000000000000module Main.Sample where import qualified Data.Vector as B import Test.QuickCheck.Instances () import qualified Test.Tasty.QuickCheck as C import qualified VectorBuilder.Builder as A import Prelude 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 _ -> error "Bug" vector-builder-0.3.8.5/vector-builder.cabal0000644000000000000000000000720507346545000016722 0ustar0000000000000000name: vector-builder version: 0.3.8.5 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: NoImplicitPrelude NoMonomorphismRestriction Arrows BangPatterns ConstraintKinds DataKinds DefaultSignatures DeriveDataTypeable DeriveFoldable DeriveFunctor DeriveGeneric DeriveTraversable EmptyDataDecls FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving LambdaCase LiberalTypeSynonyms MagicHash MultiParamTypeClasses MultiWayIf OverloadedStrings ParallelListComp PatternGuards QuasiQuotes RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving TemplateHaskell TupleSections TypeFamilies TypeOperators UnboxedTuples default-language: Haskell2010 exposed-modules: VectorBuilder.Alternative VectorBuilder.Builder VectorBuilder.MonadPlus VectorBuilder.MVector VectorBuilder.Vector other-modules: VectorBuilder.Core.Builder VectorBuilder.Core.Update VectorBuilder.Prelude build-depends: base >=4.10 && <5 , vector >=0.12 && <0.14 test-suite tests type: exitcode-stdio-1.0 hs-source-dirs: tests main-is: Main.hs other-modules: Main.Sample default-extensions: NoImplicitPrelude NoMonomorphismRestriction Arrows BangPatterns ConstraintKinds DataKinds DefaultSignatures DeriveDataTypeable DeriveFoldable DeriveFunctor DeriveGeneric DeriveTraversable EmptyDataDecls FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving LambdaCase LiberalTypeSynonyms MagicHash MultiParamTypeClasses MultiWayIf OverloadedStrings ParallelListComp PatternGuards QuasiQuotes RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving TemplateHaskell TupleSections TypeFamilies TypeOperators UnboxedTuples default-language: Haskell2010 build-depends: attoparsec >=0.13 && <0.15 , 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