pipes-vector 0.3.0.0 → 0.5.1
raw patch · 3 files changed
+90/−53 lines, 3 filesdep ~pipesdep ~transformersPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: pipes, transformers
API changes (from Hackage documentation)
- Control.Proxy.Vector: runToVectorK :: (PrimMonad m, Unbox e, Monad (p a' a b' b m), Proxy p, MonadTrans (p a' a b' b)) => (q -> StateP (ToVectorState MVector m e) p a' a b' b m r) -> (q -> p a' a b' b m (Vector e))
- Control.Proxy.Vector: runToVectorP :: (PrimMonad m, Unbox e, Monad (p a' a b' b m), Proxy p, MonadTrans (p a' a b' b)) => StateP (ToVectorState MVector m e) p a' a b' b m r -> p a' a b' b m (Vector e)
- Control.Proxy.Vector: toVectorD :: (PrimMonad m, Proxy p, MVector v e) => () -> Consumer (StateP (ToVectorState v m e) p) e m r
+ Pipes.Vector: data ToVector v e m r
+ Pipes.Vector: instance (Monad m, Functor m) => Applicative (ToVector v e m)
+ Pipes.Vector: instance Functor m => Functor (ToVector v e m)
+ Pipes.Vector: instance Monad m => Monad (ToVector v e m)
+ Pipes.Vector: runToVector :: (PrimMonad m, Vector v e) => ToVector v e m r -> m (v e)
+ Pipes.Vector: runToVectorP :: (PrimMonad m, Vector v e) => Proxy a' a b' b (ToVector v e m) r -> Proxy a' a b' b m (v e)
+ Pipes.Vector: toVector :: (PrimMonad m, MVector (Mutable v) e) => Consumer e (ToVector v e m) r
Files
- Control/Proxy/Vector.hs +0/−47
- Pipes/Vector.hs +84/−0
- pipes-vector.cabal +6/−6
− Control/Proxy/Vector.hs
@@ -1,47 +0,0 @@-module Control.Proxy.Vector ( toVectorD, runToVectorK, runToVectorP ) where--import Control.Applicative-import Control.Monad-import Control.Monad.Primitive-import Control.Proxy-import Control.Proxy.Trans.State as S-import qualified Data.Vector.Unboxed.Mutable as MVU-import qualified Data.Vector.Generic as V-import qualified Data.Vector.Generic.Mutable as M-import qualified Data.Vector.Unboxed as VU--data ToVectorState v m e = ToVecS { result :: v (PrimState m) e- , idx :: Int- }--maxChunkSize = 8*1024*1024--toVectorD- :: (PrimMonad m, Proxy p, M.MVector v e)- => () -> Consumer (S.StateP (ToVectorState v m e) p) e m r-toVectorD () = forever $ do- length <- M.length . result <$> get- pos <- idx `liftM` get- when (pos >= length) $ do- v <- result `liftM` get- v' <- lift $ M.unsafeGrow v (min length maxChunkSize)- modify $ \(ToVecS r i) -> ToVecS v' i- r <- request ()- v <- result `liftM` get- lift $ M.unsafeWrite v pos r- modify $ \(ToVecS r i) -> ToVecS r (pos+1)--runToVectorK- :: (PrimMonad m, MVU.Unbox e, Monad (p a' a b' b m), Proxy p, MonadTrans (p a' a b' b))- => (q -> StateP (ToVectorState VU.MVector m e) p a' a b' b m r)- -> (q -> p a' a b' b m (VU.Vector e))-runToVectorK k q = runToVectorP (k q)--runToVectorP- :: (PrimMonad m, MVU.Unbox e, Monad (p a' a b' b m), Proxy p, MonadTrans (p a' a b' b))- => StateP (ToVectorState VU.MVector m e) p a' a b' b m r -> p a' a b' b m (VU.Vector e)-runToVectorP x = do- v <- lift $ MVU.new 10- s <- execStateP (ToVecS v 0) x- frozen <- lift $ V.freeze (result s)- return $ VU.take (idx s) frozen
+ Pipes/Vector.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE RankNTypes, FlexibleContexts, GeneralizedNewtypeDeriving #-}++{-| Pipes for interfacing with "Data.Vector".++ Note that this only provides functionality for building @Vectors@+ from Pipes; as @Vectors@ are @Foldable@ the inverse can be+ accomplished with "Pipes.each".+-}++module Pipes.Vector (+ -- * Usage+ -- $usage+ -- * Building Vectors from Pipes+ toVector,+ runToVectorP,+ runToVector,+ ToVector+ ) where++import Control.Applicative+import Control.Monad+import Control.Monad.Trans.State.Strict as S+import Control.Monad.Primitive+import Pipes+import Pipes.Internal (unsafeHoist)+import Pipes.Lift+import qualified Data.Vector.Generic as V+import qualified Data.Vector.Generic.Mutable as M++data ToVectorState v e m = ToVecS { result :: V.Mutable v (PrimState m) e+ , idx :: Int+ }++newtype ToVector v e m r = TV {unTV :: S.StateT (ToVectorState v e m) m r}+ deriving (Functor, Applicative, Monad)++maxChunkSize :: Int+maxChunkSize = 8*1024*1024++-- | Consume items from a Pipe and place them into a vector+--+-- For efficient filling, the vector is grown geometrically up to a+-- maximum chunk size.+toVector+ :: (PrimMonad m, M.MVector (V.Mutable v) e)+ => Consumer e (ToVector v e m) r+toVector = forever $ do+ length <- M.length . result <$> lift (TV get)+ pos <- idx `liftM` lift (TV get)+ lift $ TV $ when (pos >= length) $ do+ v <- result `liftM` get+ v' <- lift $ M.unsafeGrow v (min length maxChunkSize)+ modify $ \(ToVecS r i) -> ToVecS v' i+ r <- await+ lift $ TV $ do+ v <- result `liftM` get+ lift $ M.unsafeWrite v pos r+ modify $ \(ToVecS r i) -> ToVecS r (pos+1)++-- | Extract and freeze the constructed vector+runToVectorP+ :: (PrimMonad m, V.Vector v e)+ => Proxy a' a b' b (ToVector v e m) r+ -> Proxy a' a b' b m (v e)+runToVectorP x = do+ v <- lift $ M.new 10+ s <- execStateP (ToVecS v 0) (hoist unTV x)+ frozen <- lift $ V.freeze (result s)+ return $ V.take (idx s) frozen++runToVector :: (PrimMonad m, V.Vector v e)+ => ToVector v e m r -> m (v e)+runToVector (TV a) = do+ v <- M.new 10+ s <- execStateT a (ToVecS v 0)+ frozen <- V.freeze (result s)+ return $ V.take (idx s) frozen++{- $usage++ >>> run $ runToVectorP $ each [1..5::Int] >-> toVector+ fromList [1,2,3,4,5]++-}
pipes-vector.cabal view
@@ -1,7 +1,7 @@ name: pipes-vector-version: 0.3.0.0-synopsis: Various proxies for streaming data into and out of vectors-description: Proxies for streaming data into and out of vectors. +version: 0.5.1+synopsis: Various proxies for streaming data into vectors+description: Proxies for streaming data into vectors. license: BSD3 license-file: LICENSE author: Ben Gamari@@ -12,10 +12,10 @@ cabal-version: >=1.10 library- exposed-modules: Control.Proxy.Vector+ exposed-modules: Pipes.Vector build-depends: base >=3.0 && <5,- transformers >= 0.3 && < 1.0,+ transformers >= 0.2 && < 1.0, primitive >=0.4 && <1.0,- pipes >=3.3 && <3.4,+ pipes >=4.0 && <5.0, vector >=0.9 && <1.0 default-language: Haskell2010