packages feed

repa-stream 4.1.0.1 → 4.2.2.1

raw patch · 13 files changed

+460/−417 lines, 13 filesdep +repa-scalardep ~basedep ~primitivePVP ok

version bump matches the API change (PVP)

Dependencies added: repa-scalar

Dependency ranges changed: base, primitive

API changes (from Hackage documentation)

- Data.Repa.Chain: _lenSeg :: Folds sLens sVals n a b -> !Int
- Data.Repa.Chain: _nameSeg :: Folds sLens sVals n a b -> !(Option n)
- Data.Repa.Chain: _stateLens :: Folds sLens sVals n a b -> !sLens
- Data.Repa.Chain: _stateVals :: Folds sLens sVals n a b -> !sVals
- Data.Repa.Chain: _valSeg :: Folds sLens sVals n a b -> !b
- Data.Repa.Chain: mchainSize :: Chain m s a -> Size
- Data.Repa.Chain: mchainState :: Chain m s a -> s
- Data.Repa.Chain: mchainStep :: Chain m s a -> s -> m (Step s a)
- Data.Repa.Option: None :: Option a
- Data.Repa.Option: None2 :: Option2 a b
- Data.Repa.Option: None3 :: Option3 a b c
- Data.Repa.Option: Some :: !a -> Option a
- Data.Repa.Option: Some2 :: !a -> !b -> Option2 a b
- Data.Repa.Option: Some3 :: !a -> !b -> !c -> Option3 a b c
- Data.Repa.Option: data Option a
- Data.Repa.Option: data Option2 a b
- Data.Repa.Option: data Option3 a b c
- Data.Repa.Option: fromOption :: Option a -> Maybe a
- Data.Repa.Option: fromOption2 :: Option2 a b -> Maybe (a, b)
- Data.Repa.Option: fromOption3 :: Option3 a b c -> Maybe (a, b, c)
- Data.Repa.Option: instance (Show a, Show b) => Show (Option2 a b)
- Data.Repa.Option: instance (Show a, Show b, Show c) => Show (Option3 a b c)
- Data.Repa.Option: instance Show a => Show (Option a)
- Data.Repa.Option: toOption :: Maybe a -> Option a
- Data.Repa.Option: toOption2 :: Maybe (a, b) -> Option2 a b
- Data.Repa.Option: toOption3 :: Maybe (a, b, c) -> Option3 a b c
- Data.Repa.Vector.Generic: _lenSeg :: Folds sLens sVals n a b -> !Int
- Data.Repa.Vector.Generic: _nameSeg :: Folds sLens sVals n a b -> !(Option n)
- Data.Repa.Vector.Generic: _stateLens :: Folds sLens sVals n a b -> !sLens
- Data.Repa.Vector.Generic: _stateVals :: Folds sLens sVals n a b -> !sVals
- Data.Repa.Vector.Generic: _valSeg :: Folds sLens sVals n a b -> !b
- Data.Repa.Vector.Unboxed: _lenSeg :: Folds sLens sVals n a b -> !Int
- Data.Repa.Vector.Unboxed: _nameSeg :: Folds sLens sVals n a b -> !(Option n)
- Data.Repa.Vector.Unboxed: _stateLens :: Folds sLens sVals n a b -> !sLens
- Data.Repa.Vector.Unboxed: _stateVals :: Folds sLens sVals n a b -> !sVals
- Data.Repa.Vector.Unboxed: _valSeg :: Folds sLens sVals n a b -> !b
+ Data.Repa.Chain: StepUnfoldBump :: s -> StepUnfold s a
+ Data.Repa.Chain: StepUnfoldFinish :: s -> StepUnfold s a
+ Data.Repa.Chain: StepUnfoldGive :: a -> s -> StepUnfold s a
+ Data.Repa.Chain: StepUnfoldNext :: a -> s -> StepUnfold s a
+ Data.Repa.Chain: [_lenSeg] :: Folds sLens sVals n a b -> !Int
+ Data.Repa.Chain: [_nameSeg] :: Folds sLens sVals n a b -> !(Option n)
+ Data.Repa.Chain: [_stateLens] :: Folds sLens sVals n a b -> !sLens
+ Data.Repa.Chain: [_stateVals] :: Folds sLens sVals n a b -> !sVals
+ Data.Repa.Chain: [_valSeg] :: Folds sLens sVals n a b -> !b
+ Data.Repa.Chain: [mchainSize] :: Chain m s a -> Size
+ Data.Repa.Chain: [mchainState] :: Chain m s a -> s
+ Data.Repa.Chain: [mchainStep] :: Chain m s a -> s -> m (Step s a)
+ Data.Repa.Chain: data StepUnfold s a
+ Data.Repa.Chain: unfoldsC :: Monad m => (a -> k -> m (StepUnfold k b)) -> k -> Chain m s a -> Chain m (s, k, Option a) b
+ Data.Repa.Stream: replicatesS :: Monad m => Stream m (Int, a) -> Stream m a
+ Data.Repa.Vector.Generic: [_lenSeg] :: Folds sLens sVals n a b -> !Int
+ Data.Repa.Vector.Generic: [_nameSeg] :: Folds sLens sVals n a b -> !(Option n)
+ Data.Repa.Vector.Generic: [_stateLens] :: Folds sLens sVals n a b -> !sLens
+ Data.Repa.Vector.Generic: [_stateVals] :: Folds sLens sVals n a b -> !sVals
+ Data.Repa.Vector.Generic: [_valSeg] :: Folds sLens sVals n a b -> !b
+ Data.Repa.Vector.Generic: replicates :: (Vector v (Int, a), Vector v a) => v (Int, a) -> v a
+ Data.Repa.Vector.Unboxed: [_lenSeg] :: Folds sLens sVals n a b -> !Int
+ Data.Repa.Vector.Unboxed: [_nameSeg] :: Folds sLens sVals n a b -> !(Option n)
+ Data.Repa.Vector.Unboxed: [_stateLens] :: Folds sLens sVals n a b -> !sLens
+ Data.Repa.Vector.Unboxed: [_stateVals] :: Folds sLens sVals n a b -> !sVals
+ Data.Repa.Vector.Unboxed: [_valSeg] :: Folds sLens sVals n a b -> !b
- Data.Repa.Stream: compactInS :: Monad m => (a -> a -> (Maybe a, a)) -> Stream m a -> Stream m a
+ Data.Repa.Stream: compactInS :: Monad m => (a -> a -> (a, Maybe a)) -> Stream m a -> Stream m a
- Data.Repa.Stream: compactS :: Monad m => (s -> a -> (Maybe b, s)) -> s -> Stream m a -> Stream m b
+ Data.Repa.Stream: compactS :: Monad m => (s -> a -> (s, Maybe b)) -> s -> Stream m a -> Stream m b
- Data.Repa.Vector.Generic: compact :: (Vector v a, Vector v b) => (s -> a -> (Maybe b, s)) -> s -> v a -> v b
+ Data.Repa.Vector.Generic: compact :: (Vector v a, Vector v b) => (s -> a -> (s, Maybe b)) -> s -> v a -> v b
- Data.Repa.Vector.Generic: compactIn :: Vector v a => (a -> a -> (Maybe a, a)) -> v a -> v a
+ Data.Repa.Vector.Generic: compactIn :: Vector v a => (a -> a -> (a, Maybe a)) -> v a -> v a
- Data.Repa.Vector.Unboxed: compact :: (Unbox a, Unbox b) => (s -> a -> (Maybe b, s)) -> s -> Vector a -> Vector b
+ Data.Repa.Vector.Unboxed: compact :: (Unbox a, Unbox b) => (s -> a -> (s, Maybe b)) -> s -> Vector a -> Vector b
- Data.Repa.Vector.Unboxed: compactIn :: Unbox a => (a -> a -> (Maybe a, a)) -> Vector a -> Vector a
+ Data.Repa.Vector.Unboxed: compactIn :: Unbox a => (a -> a -> (a, Maybe a)) -> Vector a -> Vector a

Files

Data/Repa/Chain.hs view
@@ -14,6 +14,10 @@         -- * Folding         , foldsC, Folds(..) +        -- * Unfolding+        , unfoldsC+        , StepUnfold    (..)+         -- * Scanning         , scanMaybeC 
Data/Repa/Chain/Folds.hs view
@@ -2,8 +2,8 @@ module Data.Repa.Chain.Folds         (foldsC, Folds (..)) where-import Data.Repa.Option import Data.Repa.Chain.Base+import Data.Repa.Scalar.Option import Data.Vector.Fusion.Stream.Size  as S #include "repa-stream.h" 
Data/Repa/Chain/Scan.hs view
@@ -1,12 +1,63 @@  module Data.Repa.Chain.Scan-        ( scanMaybeC+        ( StepUnfold  (..)+        , unfoldsC+        , scanMaybeC         , groupsByC) where import Data.Repa.Chain.Base+import Data.Repa.Scalar.Option import qualified Data.Vector.Fusion.Stream.Size  as S #include "repa-stream.h" ++-------------------------------------------------------------------------------+-- | Segmented unfold.+-- +--   The worker function takes the current element from the input stream +--   and current state. +--+--   If the worker returns Just x then that output element will be placed+--   in the output stream, and it will be called again with the same+--   input elemenent and next state. +--+--   If the worker returns Nothing then we advance to the next element+--   of the input stream.+--+unfoldsC+        :: Monad m+        => (a -> k -> m (StepUnfold k b))       -- ^ Worker function.+        -> k                                    -- ^ Initial state for the unfold.+        -> Chain m s             a              -- ^ Input elements.+        -> Chain m (s, k, Option a) b           -- ^ Output elements.++unfoldsC f k0 (Chain _ s0 istep)+ = Chain S.Unknown (s0, k0, None) ostep+ where+        ostep  (s1, k1, None)+         =  istep s1 >>= \rs+         -> case rs of+                Yield xa s2             -> return $ Skip     (s2, k1, Some xa)+                Skip     s2             -> return $ Skip     (s2, k1, None)+                Done     s2             -> return $ Done     (s2, k1, None)++        ostep  (s1, k1, Some xa)+         = f xa k1   >>= \kmb+         -> case kmb of+                StepUnfoldGive xb k2    -> return $ Yield xb (s1, k2, Some xa)+                StepUnfoldNext xb k2    -> return $ Yield xb (s1, k2, None)  +                StepUnfoldBump    k2    -> return $ Skip     (s1, k2, Some xa)+                StepUnfoldFinish  k2    -> return $ Skip     (s1, k2, None)+        {-# INLINE_INNER ostep #-}+{-# INLINE_STREAM unfoldsC #-}+++data StepUnfold s a+        = StepUnfoldGive    a s+        | StepUnfoldNext    a s+        | StepUnfoldBump      s+        | StepUnfoldFinish    s+        deriving Show  ------------------------------------------------------------------------------- -- | Perform a left-to-right scan through an input vector, maintaining a state
Data/Repa/Chain/Weave.hs view
@@ -6,8 +6,8 @@         , Move  (..), move         , Option (..)) where-import Data.Repa.Option import Data.Repa.Chain.Base+import Data.Repa.Scalar.Option import qualified Data.Vector.Fusion.Stream.Size  as S #include "repa-stream.h" 
− Data/Repa/Option.hs
@@ -1,86 +0,0 @@---- | Data types used during low-level fusion optimisations.--- ---   These types are synonyms for @Maybe (a, b)@, which are strict in the---   components. They can be used to ensure that we do not suspend the---   computation that produces these components in fused code.----module Data.Repa.Option-        ( -- * Single component-          Option  (..)-        , fromOption,  toOption--          -- * Two components-        , Option2 (..)-        , fromOption2, toOption2--          -- * Three components-        , Option3 (..)-        , fromOption3, toOption3)-where------------------------------------------------------------------------------------- | A strict `Maybe` type.-data Option a-        = Some !a-        | None -        deriving Show---- | Convert a `Maybe` to an `Option`.-toOption :: Maybe a -> Option a-toOption Nothing        = None-toOption (Just x)       = Some x-{-# INLINE toOption #-}----- | Convert an `Option` to a `Maybe`.-fromOption :: Option a -> Maybe a-fromOption None         = Nothing-fromOption (Some x)     = Just x-{-# INLINE fromOption #-}------------------------------------------------------------------------------------- | A strict `Maybe` type, with two parameters.-data Option2 a b-        = Some2 !a !b-        | None2 -        deriving Show----- | Convert a `Maybe` to an `Option2`.-toOption2 :: Maybe (a, b) -> Option2 a b-toOption2 Nothing        = None2-toOption2 (Just (x, y))  = Some2 x y-{-# INLINE toOption2 #-}----- | Convert an `Option2` to a `Maybe`.-fromOption2 :: Option2 a b -> Maybe (a, b)-fromOption2 None2        = Nothing-fromOption2 (Some2 x y)  = Just (x, y)-{-# INLINE fromOption2 #-}------------------------------------------------------------------------------------- | A strict `Maybe` type with three parameters.-data Option3 a b c-        = Some3 !a !b !c-        | None3 -        deriving Show----- | Convert a `Maybe` to an `Option3`.-toOption3 :: Maybe (a, b, c) -> Option3 a b c-toOption3 Nothing          = None3-toOption3 (Just (x, y, z)) = Some3 x y z-{-# INLINE toOption3 #-}----- | Convert an `Option2` to a `Maybe`.-fromOption3 :: Option3 a b c -> Maybe (a, b, c)-fromOption3 None3          = Nothing-fromOption3 (Some3 x y z)  = Just (x, y, z)-{-# INLINE fromOption3 #-}-
Data/Repa/Stream.hs view
@@ -2,20 +2,37 @@ -- | * See the "Data.Repa.Vector.Unboxed" module for examples of how these --     functions can be used. module Data.Repa.Stream-        ( extractS-        , insertS-        , mergeS-        , compactS+        ( -- * Compacting+          compactS         , compactInS++          -- * Concatenating         , catMaybesS-        , findSegmentsS++          -- * Dicing         , diceSepS-        , startLengthsOfSegsS++          -- * Extracting+        , extractS++          -- * Inserting+        , insertS++          -- * Merging+        , mergeS++          -- * Padding         , padForwardS -          -- * Unsafe operators-        , unsafeRatchetS)+          -- * Ratcheting+        , unsafeRatchetS +          -- * Replicating+        , replicatesS++          -- * Segmenting+        , findSegmentsS+        , startLengthsOfSegsS) where import Data.Repa.Stream.Concat import Data.Repa.Stream.Compact@@ -25,5 +42,6 @@ import Data.Repa.Stream.Merge import Data.Repa.Stream.Pad import Data.Repa.Stream.Ratchet+import Data.Repa.Stream.Replicate import Data.Repa.Stream.Segment 
Data/Repa/Stream/Compact.hs view
@@ -15,7 +15,7 @@ -- compactS         :: Monad m-        => (s -> a -> (Maybe b, s))     -- ^ Worker function.+        => (s -> a -> (s, Maybe b))     -- ^ Worker function.         -> s                            -- ^ Starting state         -> Stream m a                   -- ^ Input elements.         -> Stream m b@@ -28,9 +28,8 @@          -> case m of                 Yield x si'                           -> case f s x of-                        (Nothing, s')   -> return $ Skip    (si', s')-                        (Just y,  s')   -> return $ Yield y (si', s')-+                        (s', Nothing)   -> return $ Skip    (si', s')+                        (s', Just y)    -> return $ Yield y (si', s')                 Skip si'                -> return $ Skip    (si', s)                 Done                    -> return $ Done         {-# INLINE_INNER ostep #-}@@ -41,7 +40,7 @@ --   initial state, and add the final state to the end of the output. compactInS         :: Monad m-        => (a -> a -> (Maybe a, a))     -- ^ Worker function.+        => (a -> a -> (a, Maybe a))     -- ^ Worker function.         -> Stream m a                   -- ^ Input elements.         -> Stream m a @@ -60,9 +59,8 @@          -> case m of                 Yield x si'                       -> case f s x of-                        (Nothing, s')   -> return $ Skip    (si', Just s')-                        (Just y,  s')   -> return $ Yield y (si', Just s')-+                        (s', Nothing)   -> return $ Skip    (si', Just s')+                        (s', Just y)    -> return $ Yield y (si', Just s')                 Skip si'                -> return $ Skip    (si', ms)                 Done                    -> return $ Yield s (si,  Nothing)         {-# INLINE_INNER ostep #-}
Data/Repa/Stream/Merge.hs view
@@ -3,7 +3,7 @@         (mergeS) where import Data.Vector.Fusion.Stream.Monadic         (Stream(..), Step(..))-import Data.Repa.Option+import Data.Repa.Scalar.Option import qualified Data.Vector.Fusion.Stream.Size  as S #include "repa-stream.h" 
Data/Repa/Stream/Pad.hs view
@@ -3,7 +3,7 @@         (padForwardS) where import Data.Vector.Fusion.Stream.Monadic         (Stream(..), Step(..))-import Data.Repa.Option+import Data.Repa.Scalar.Option import qualified Data.Vector.Fusion.Stream.Size  as S #include "repa-stream.h" 
+ Data/Repa/Stream/Replicate.hs view
@@ -0,0 +1,40 @@++module Data.Repa.Stream.Replicate+        (replicatesS)+where+import Data.Vector.Fusion.Stream.Monadic         (Stream(..), Step(..))+import qualified Data.Vector.Fusion.Stream.Size  as S+#include "repa-stream.h"+++-- | Segmented replicate.+--   +--   Given a stream of counts and values, produce a result stream where+--   each value is replciated the associated number of times.+--+replicatesS +        :: Monad m+        => Stream m (Int, a)+        -> Stream m a++replicatesS (Stream istepA sA0 _)+ = Stream ostep (sA0, 0, Nothing) S.Unknown+ where+        -- Pull the next element from the source stream.+        ostep (sA, 0, mv)+         =  istepA sA >>= \rA+         -> case rA of+                Done                 -> return Done+                Skip sA'             -> return $ Skip (sA', 0,   mv)+                Yield (len, val) sA' -> return $ Skip (sA', len, Just val)++        -- Should never be entered, as we'll always have a value+        -- when the count is non-zero.+        ostep (_, _, Nothing)       +         = return Done++        ostep (sA, len, mv@(Just val))+         = return $ Yield val (sA, len - 1, mv)+        {-# INLINE_INNER ostep #-}+{-# INLINE_STREAM replicatesS #-}+
Data/Repa/Vector/Generic.hs view
@@ -4,48 +4,49 @@ --   * NOTE: Support for streams of unknown length is not complete. -- module Data.Repa.Vector.Generic-        ( -- * Stream functions+        ( -- * Stream operators           unstreamToVector2         , unstreamToMVector2 -          -- * Chain functions-        , chainOfVector-        , unchainToVector-        , unchainToMVector+          -- ** Compacting+        , compact+        , compactIn -          -- * Generating-        , ratchet+          -- ** Dicing+        , findSegments+        , findSegmentsFrom+        , diceSep -          -- * Extracting+          -- ** Extracting         , extract -          -- * Inserting+          -- ** Inserting         , insert -          -- * Merging+          -- ** Merging         , merge         , mergeMaybe -          -- * Splitting-        , findSegments-        , findSegmentsFrom-        , diceSep--          -- * Compacting-        , compact-        , compactIn--          -- * Padding+          -- ** Padding         , padForward -          -- * Scanning-        , scanMaybe+          -- ** Ratcheting+        , ratchet -          -- * Grouping-        , groupsBy+          -- ** Replicating+        , replicates +          -- * Chain operators+        , chainOfVector+        , unchainToVector+        , unchainToMVector+           -- * Folding-        , folds, C.Folds(..))+        , folds, C.Folds(..)++          -- * Scanning+        , scanMaybe+        , groupsBy) where import Data.Repa.Stream.Compact import Data.Repa.Stream.Concat@@ -55,8 +56,9 @@ import Data.Repa.Stream.Merge import Data.Repa.Stream.Pad import Data.Repa.Stream.Ratchet+import Data.Repa.Stream.Replicate import Data.Repa.Stream.Segment-import Data.Repa.Option+import Data.Repa.Scalar.Option import Data.IORef import System.IO.Unsafe import Control.Monad.ST@@ -138,141 +140,100 @@   ---------------------------------------------------------------------------------- | Produce a chain from a generic vector.-chainOfVector -        :: (Monad m, GV.Vector v a)-        => v a -> Chain m Int a--chainOfVector vec- = Chain (S.Exact len) 0 step- where-        !len  = GV.length vec--        step !i-         | i >= len-         = return $ Done  i--         | otherwise    -         = return $ Yield (GV.unsafeIndex vec i) (i + 1)-        {-# INLINE_INNER step #-}-{-# INLINE_STREAM chainOfVector #-}-+-- | Combination of `fold` and `filter`. +--   +--   We walk over the stream front to back, maintaining an accumulator.+--   At each point we can chose to emit an element (or not)+--+compact :: (GV.Vector v a, GV.Vector v b)+        => (s -> a -> (s, Maybe b))     -- ^ Worker function+        -> s                            -- ^ Starting state+        -> v a                          -- ^ Input vector+        -> v b ----------------------------------------------------------------------------------- | Compute a chain into a generic vector.-unchainToVector-        :: (PrimMonad m, GV.Vector v a)-        => C.Chain m s a  -> m (v a, s)-unchainToVector chain- = do   (mvec, c') <- unchainToMVector chain-        vec        <- GV.unsafeFreeze mvec-        return (vec, c')-{-# INLINE_STREAM unchainToVector #-}+compact f s0 vec+        = GV.unstream $ compactS f s0 $ GV.stream vec+{-# INLINE compact #-}  --- | Compute a chain into a generic mutable vector.-unchainToMVector-        :: (PrimMonad m, GM.MVector v a)-        => Chain m s a-        -> m (v (PrimState m) a, s)+-- | Like `compact` but use the first value of the stream as the +--   initial state, and add the final state to the end of the output.+compactIn+        :: GV.Vector v a+        => (a -> a -> (a, Maybe a))     -- ^ Worker function.+        -> v a                          -- ^ Input elements.+        -> v a -unchainToMVector (Chain sz s0 step)- = case sz of-        S.Exact i       -> unchainToMVector_max     i  s0 step-        S.Max i         -> unchainToMVector_max     i  s0 step-        S.Unknown       -> unchainToMVector_unknown 32 s0 step-{-# INLINE_STREAM unchainToMVector #-}+compactIn f vec+        = GV.unstream $ compactInS f $ GV.stream vec+{-# INLINE compactIn #-}  --- unchain when we known the maximum size of the vector.-unchainToMVector_max nMax s0 step - =  GM.unsafeNew nMax >>= \vec- -> let -        go !sPEC !i !s-         =  step s >>= \m-         -> case m of-                Yield e s'-                 -> do  GM.unsafeWrite vec i e-                        go sPEC (i + 1) s'--                Skip s' -> go sPEC i s'-                Done s' -> return (GM.unsafeSlice 0 i vec, s')-        {-# INLINE_INNER go #-}+-------------------------------------------------------------------------------+-- | Given predicates that detect the beginning and end of some interesting+--   segment of information, scan through a vector looking for when these+--   segments begin and end. Return vectors of the segment starting positions+--   and lengths.+--+--   * As each segment must end on a element where the ending predicate returns+--     True, the miniumum segment length returned is 1.+--+findSegments +        :: (GV.Vector v a, GV.Vector v Int, GV.Vector v (Int, Int))+        => (a -> Bool)          -- ^ Predicate to check for start of segment.+        -> (a -> Bool)          -- ^ Predicate to check for end of segment.+        ->  v a                 -- ^ Input vector.+        -> (v Int, v Int) -    in  go SM.SPEC 0 s0-{-# INLINE_STREAM unchainToMVector_max #-}+findSegments pStart pEnd src+        = GV.unzip+        $ GV.unstream+        $ startLengthsOfSegsS+        $ findSegmentsS pStart pEnd (GV.length src - 1)+        $ SM.indexed +        $ GV.stream src+{-# INLINE findSegments #-}  --- unchain when we don't know the maximum size of the vector.-unchainToMVector_unknown nStart s0 step- =  GM.unsafeNew nStart >>= \vec0- -> let -        go !sPEC !vec !i !n !s-         =  step s >>= \m-         -> case m of-                Yield e s'-                 | i >= n       -                 -> do  vec'    <- GM.unsafeGrow vec n-                        GM.unsafeWrite vec' i e-                        go sPEC vec' (i + 1) (n + n) s'--                 | otherwise-                 -> do  GM.unsafeWrite vec i e-                        go sPEC vec  (i + 1) n s'--                Skip s' -> go sPEC vec i n s'-                Done s' -> return (GM.unsafeSlice 0 i vec, s')-        {-# INLINE_INNER go #-}+-------------------------------------------------------------------------------+-- | Given predicates that detect the beginning and end of some interesting+--   segment of information, scan through a vector looking for when these+--   segments begin and end. Return vectors of the segment starting positions+--   and lengths.+findSegmentsFrom+        :: (GV.Vector v Int, GV.Vector v (Int, Int))+        => (a -> Bool)          -- ^ Predicate to check for start of segment.+        -> (a -> Bool)          -- ^ Predicate to check for end of segment.+        -> Int                  -- ^ Input length.+        -> (Int -> a)           -- ^ Get an element from the input.+        -> (v Int, v Int) -    in go SM.SPEC vec0 0 nStart s0-{-# INLINE_STREAM unchainToMVector_unknown #-}+findSegmentsFrom pStart pEnd len get+        = GV.unzip+        $ GV.unstream+        $ startLengthsOfSegsS+        $ findSegmentsS pStart pEnd (len - 1)+        $ SM.map         (\ix -> (ix, get ix))+        $ SM.enumFromStepN 0 1 len+{-# INLINE findSegmentsFrom #-}   ---------------------------------------------------------------------------------- | Interleaved `enumFromTo`. ------   Given a vector of starting values, and a vector of stopping values, ---   produce an stream of elements where we increase each of the starting---   values to the stopping values in a round-robin order. Also produce a---   vector of result segment lengths.------ @---  unsafeRatchetS [10,20,30,40] [15,26,33,47]---  =  [10,20,30,40       -- 4---     ,11,21,31,41       -- 4---     ,12,22,32,42       -- 4---     ,13,23   ,43       -- 3---     ,14,24   ,44       -- 3---        ,25   ,45       -- 2---              ,46]      -- 1------         ^^^^             ^^^---       Elements         Lengths--- @+-- | Dice a vector stream into rows and columns. ---ratchet :: (GV.Vector v Int, GV.Vector v (Int, Int))-        => v (Int, Int)         -- ^ Starting and ending values.-        -> (v Int, v Int)       -- ^ Elements and Lengths vectors.-ratchet vStartsMax - = unsafePerformIO- $ do   -        -- Make buffers for the start values and unpack the max values.-        let (vStarts, vMax) = GV.unzip vStartsMax-        mvStarts   <- GV.thaw vStarts--        -- Make a vector for the output lengths.-        mvLens     <- GM.unsafeNew (GV.length vStartsMax)-        rmvLens    <- newIORef mvLens--        -- Run the computation-        mvStarts'  <- GM.munstream $ unsafeRatchetS mvStarts vMax rmvLens+diceSep :: (GV.Vector v a, GV.Vector v (Int, Int))+        => (a -> Bool)                  -- ^ Detect the end of a column.+        -> (a -> Bool)                  -- ^ Detect the end of a row.+        ->  v a+        -> (v (Int, Int), v (Int, Int)) -- ^ Segment starts   and lengths -        -- Read back the output segment lengths and freeze everything.-        mvLens'    <- readIORef rmvLens-        vStarts'   <- GV.unsafeFreeze mvStarts'-        vLens'     <- GV.unsafeFreeze mvLens'-        return (vStarts', vLens')-{-# INLINE ratchet #-}+diceSep pEndInner pEndBoth vec+        = runST+        $ unstreamToVector2+        $ diceSepS pEndInner pEndBoth +        $ S.liftStream+        $ GV.stream vec+{-# INLINE diceSep #-}   -------------------------------------------------------------------------------@@ -359,155 +320,174 @@   ---------------------------------------------------------------------------------- | Perform a left-to-right scan through an input vector, maintaining a state---   value between each element. For each element of input we may or may not---   produce an element of output.-scanMaybe -        :: forall v1 v2 a b s-        .  (GV.Vector v1 a, GV.Vector v2 b)-        =>  (s -> a -> (s, Maybe b))    -- ^ Worker function.-        ->  s                           -- ^ Initial state for scan.-        ->  v1 a                        -- ^ Input elements.-        -> (v2 b, s)                    -- ^ Output elements.--scanMaybe f k0 vec0- = (vec1, snd k1)- where  -        f' s x = return $ f s x+-- | Given a stream of keys and values, and a successor function for keys, +--   if the stream is has keys missing in the sequence then insert +--   the missing key, copying forward the the previous value.+padForward  +        :: (Ord k, GV.Vector v (k, a))+        => (k -> k)             -- ^ Successor function.+        -> v (k, a)             -- ^ Input keys and values.+        -> v (k, a) -        (vec1 :: v2 b, k1 :: (Int, s))-         = runST $ unchainToVector     $ C.liftChain -                 $ C.scanMaybeC f' k0  $ chainOfVector vec0-{-# INLINE scanMaybe #-}+padForward ksucc vec+        = GV.unstream+        $ padForwardS ksucc+        $ GV.stream vec+{-# INLINE padForward #-}   ---------------------------------------------------------------------------------- | From a stream of values which has consecutive runs of idential values,---   produce a stream of the lengths of these runs.--- +-- | Interleaved `enumFromTo`. +--+--   Given a vector of starting values, and a vector of stopping values, +--   produce an stream of elements where we increase each of the starting+--   values to the stopping values in a round-robin order. Also produce a+--   vector of result segment lengths.+-- -- @---  groupsBy (==) (Just ('a', 4)) ---                [\'a\', \'a\', \'a\', \'b\', \'b\', \'c\', \'d\', \'d\'] ---   => ([('a', 7), ('b', 2), ('c', 1)], Just (\'d\', 2))+--  unsafeRatchetS [10,20,30,40] [15,26,33,47]+--  =  [10,20,30,40       -- 4+--     ,11,21,31,41       -- 4+--     ,12,22,32,42       -- 4+--     ,13,23   ,43       -- 3+--     ,14,24   ,44       -- 3+--        ,25   ,45       -- 2+--              ,46]      -- 1+--+--         ^^^^             ^^^+--       Elements         Lengths -- @ ---groupsBy-        :: forall v1 v2 a-        .  (GV.Vector v1 a, GV.Vector v2 (a, Int))-        => (a -> a -> Bool)             -- ^ Comparison function.-        -> Maybe (a, Int)               -- ^ Starting element and count.-        ->  v1 a                         -- ^ Input elements.-        -> (v2 (a, Int), Maybe (a, Int))+ratchet :: (GV.Vector v Int, GV.Vector v (Int, Int))+        => v (Int, Int)         -- ^ Starting and ending values.+        -> (v Int, v Int)       -- ^ Elements and Lengths vectors.+ratchet vStartsMax + = unsafePerformIO+ $ do   +        -- Make buffers for the start values and unpack the max values.+        let (vStarts, vMax) = GV.unzip vStartsMax+        mvStarts   <- GV.thaw vStarts -groupsBy f !c !vec0- = (vec1, snd k1)- where  -        f' x y = return $ f x y+        -- Make a vector for the output lengths.+        mvLens     <- GM.unsafeNew (GV.length vStartsMax)+        rmvLens    <- newIORef mvLens -        (vec1 :: v2 (a, Int), k1)-         = runST $ unchainToVector   $ C.liftChain -                 $ C.groupsByC f' c  $ chainOfVector vec0-{-# INLINE groupsBy #-}+        -- Run the computation+        mvStarts'  <- GM.munstream $ unsafeRatchetS mvStarts vMax rmvLens +        -- Read back the output segment lengths and freeze everything.+        mvLens'    <- readIORef rmvLens+        vStarts'   <- GV.unsafeFreeze mvStarts'+        vLens'     <- GV.unsafeFreeze mvLens'+        return (vStarts', vLens')+{-# INLINE ratchet #-} + ---------------------------------------------------------------------------------- | Given predicates that detect the beginning and end of some interesting---   segment of information, scan through a vector looking for when these---   segments begin and end. Return vectors of the segment starting positions---   and lengths.------   * As each segment must end on a element where the ending predicate returns---     True, the miniumum segment length returned is 1.----findSegments -        :: (GV.Vector v a, GV.Vector v Int, GV.Vector v (Int, Int))-        => (a -> Bool)          -- ^ Predicate to check for start of segment.-        -> (a -> Bool)          -- ^ Predicate to check for end of segment.-        ->  v a                 -- ^ Input vector.-        -> (v Int, v Int)+-- | Segmented replicate.+replicates+        :: (GV.Vector v (Int, a), GV.Vector v a)+        => v (Int, a)+        -> v a -findSegments pStart pEnd src-        = GV.unzip-        $ GV.unstream-        $ startLengthsOfSegsS-        $ findSegmentsS pStart pEnd (GV.length src - 1)-        $ SM.indexed -        $ GV.stream src-{-# INLINE findSegments #-}+replicates vec+        = GV.unstream+        $ replicatesS+        $ GV.stream vec+{-# INLINE replicates #-}   ---------------------------------------------------------------------------------- | Given predicates that detect the beginning and end of some interesting---   segment of information, scan through a vector looking for when these---   segments begin and end. Return vectors of the segment starting positions---   and lengths.-findSegmentsFrom-        :: (GV.Vector v Int, GV.Vector v (Int, Int))-        => (a -> Bool)          -- ^ Predicate to check for start of segment.-        -> (a -> Bool)          -- ^ Predicate to check for end of segment.-        -> Int                  -- ^ Input length.-        -> (Int -> a)           -- ^ Get an element from the input.-        -> (v Int, v Int)+-- | Produce a chain from a generic vector.+chainOfVector +        :: (Monad m, GV.Vector v a)+        => v a -> Chain m Int a -findSegmentsFrom pStart pEnd len get-        = GV.unzip-        $ GV.unstream-        $ startLengthsOfSegsS-        $ findSegmentsS pStart pEnd (len - 1)-        $ SM.map         (\ix -> (ix, get ix))-        $ SM.enumFromStepN 0 1 len-{-# INLINE findSegmentsFrom #-}+chainOfVector vec+ = Chain (S.Exact len) 0 step+ where+        !len  = GV.length vec +        step !i+         | i >= len+         = return $ Done  i +         | otherwise    +         = return $ Yield (GV.unsafeIndex vec i) (i + 1)+        {-# INLINE_INNER step #-}+{-# INLINE_STREAM chainOfVector #-}++ ---------------------------------------------------------------------------------- | Dice a vector stream into rows and columns.----diceSep :: (GV.Vector v a, GV.Vector v (Int, Int))-        => (a -> Bool)                  -- ^ Detect the end of a column.-        -> (a -> Bool)                  -- ^ Detect the end of a row.-        ->  v a-        -> (v (Int, Int), v (Int, Int)) -- ^ Segment starts   and lengths+-- | Compute a chain into a generic vector.+unchainToVector+        :: (PrimMonad m, GV.Vector v a)+        => C.Chain m s a  -> m (v a, s)+unchainToVector chain+ = do   (mvec, c') <- unchainToMVector chain+        vec        <- GV.unsafeFreeze mvec+        return (vec, c')+{-# INLINE_STREAM unchainToVector #-} -diceSep pEndInner pEndBoth vec-        = runST-        $ unstreamToVector2-        $ diceSepS pEndInner pEndBoth -        $ S.liftStream-        $ GV.stream vec-{-# INLINE diceSep #-} +-- | Compute a chain into a generic mutable vector.+unchainToMVector+        :: (PrimMonad m, GM.MVector v a)+        => Chain m s a+        -> m (v (PrimState m) a, s) ----------------------------------------------------------------------------------- | Combination of `fold` and `filter`. ---   ---   We walk over the stream front to back, maintaining an accumulator.---   At each point we can chose to emit an element (or not)----compact-        :: (GV.Vector v a, GV.Vector v b)-        => (s -> a -> (Maybe b, s))     -- ^ Worker function-        -> s                            -- ^ Starting state-        -> v a                          -- ^ Input vector-        -> v b+unchainToMVector (Chain sz s0 step)+ = case sz of+        S.Exact i       -> unchainToMVector_max     i  s0 step+        S.Max i         -> unchainToMVector_max     i  s0 step+        S.Unknown       -> unchainToMVector_unknown 32 s0 step+{-# INLINE_STREAM unchainToMVector #-} -compact f s0 vec-        = GV.unstream $ compactS f s0 $ GV.stream vec-{-# INLINE compact #-} +-- unchain when we known the maximum size of the vector.+unchainToMVector_max nMax s0 step + =  GM.unsafeNew nMax >>= \vec+ -> let +        go !sPEC !i !s+         =  step s >>= \m+         -> case m of+                Yield e s'+                 -> do  GM.unsafeWrite vec i e+                        go sPEC (i + 1) s' --- | Like `compact` but use the first value of the stream as the ---   initial state, and add the final state to the end of the output.-compactIn-        :: GV.Vector v a-        => (a -> a -> (Maybe a, a))     -- ^ Worker function.-        -> v a                          -- ^ Input elements.-        -> v a+                Skip s' -> go sPEC i s'+                Done s' -> return (GM.unsafeSlice 0 i vec, s')+        {-# INLINE_INNER go #-} -compactIn f vec-        = GV.unstream $ compactInS f $ GV.stream vec-{-# INLINE compactIn #-}+    in  go SM.SPEC 0 s0+{-# INLINE_STREAM unchainToMVector_max #-}  +-- unchain when we don't know the maximum size of the vector.+unchainToMVector_unknown nStart s0 step+ =  GM.unsafeNew nStart >>= \vec0+ -> let +        go !sPEC !vec !i !n !s+         =  step s >>= \m+         -> case m of+                Yield e s'+                 | i >= n       +                 -> do  vec'    <- GM.unsafeGrow vec n+                        GM.unsafeWrite vec' i e+                        go sPEC vec' (i + 1) (n + n) s'++                 | otherwise+                 -> do  GM.unsafeWrite vec i e+                        go sPEC vec  (i + 1) n s'++                Skip s' -> go sPEC vec i n s'+                Done s' -> return (GM.unsafeSlice 0 i vec, s')+        {-# INLINE_INNER go #-}++    in go SM.SPEC vec0 0 nStart s0+{-# INLINE_STREAM unchainToMVector_unknown #-}++ ------------------------------------------------------------------------------- -- | Segmented fold over vectors of segment lengths and input values. --@@ -545,18 +525,53 @@   ---------------------------------------------------------------------------------- | Given a stream of keys and values, and a successor function for keys, ---   if the stream is has keys missing in the sequence then insert ---   the missing key, copying forward the the previous value.-padForward  -        :: (Ord k, GV.Vector v (k, a))-        => (k -> k)             -- ^ Successor function.-        -> v (k, a)             -- ^ Input keys and values.-        -> v (k, a)+-- | Perform a left-to-right scan through an input vector, maintaining a state+--   value between each element. For each element of input we may or may not+--   produce an element of output.+scanMaybe +        :: forall v1 v2 a b s+        .  (GV.Vector v1 a, GV.Vector v2 b)+        =>  (s -> a -> (s, Maybe b))    -- ^ Worker function.+        ->  s                           -- ^ Initial state for scan.+        ->  v1 a                        -- ^ Input elements.+        -> (v2 b, s)                    -- ^ Output elements. -padForward ksucc vec-        = GV.unstream-        $ padForwardS ksucc-        $ GV.stream vec-{-# INLINE padForward #-}+scanMaybe f k0 vec0+ = (vec1, snd k1)+ where  +        f' s x = return $ f s x++        (vec1 :: v2 b, k1 :: (Int, s))+         = runST $ unchainToVector     $ C.liftChain +                 $ C.scanMaybeC f' k0  $ chainOfVector vec0+{-# INLINE scanMaybe #-}+++-------------------------------------------------------------------------------+-- | From a stream of values which has consecutive runs of idential values,+--   produce a stream of the lengths of these runs.+-- +-- @+--  groupsBy (==) (Just ('a', 4)) +--                [\'a\', \'a\', \'a\', \'b\', \'b\', \'c\', \'d\', \'d\'] +--   => ([('a', 7), ('b', 2), ('c', 1)], Just (\'d\', 2))+-- @+--+groupsBy+        :: forall v1 v2 a+        .  (GV.Vector v1 a, GV.Vector v2 (a, Int))+        => (a -> a -> Bool)             -- ^ Comparison function.+        -> Maybe (a, Int)               -- ^ Starting element and count.+        ->  v1 a                         -- ^ Input elements.+        -> (v2 (a, Int), Maybe (a, Int))++groupsBy f !c !vec0+ = (vec1, snd k1)+ where  +        f' x y = return $ f x y++        (vec1 :: v2 (a, Int), k1)+         = runST $ unchainToVector   $ C.liftChain +                 $ C.groupsByC f' c  $ chainOfVector vec0+{-# INLINE groupsBy #-} 
Data/Repa/Vector/Unboxed.hs view
@@ -1,48 +1,50 @@  module Data.Repa.Vector.Unboxed-        ( -- * Conversion-          chainOfVector-        , unchainToVector-        , unchainToMVector+        ( -- * Stream operators+          -- ** Compacting+          compact+        , compactIn -          -- * Generating-        , ratchet+          -- ** Dicing+        , findSegments+        , findSegmentsFrom+        , diceSep -          -- * Extracting+          -- ** Extracting         , extract -          -- * Inserting+          -- ** Inserting         , insert -          -- * Merging+          -- ** Merging         , merge         , mergeMaybe -          -- * Splitting-        , findSegments-        , findSegmentsFrom-        , diceSep+          -- ** Padding+        , padForward -          -- * Compacting-        , compact-        , compactIn+          -- ** Ratcheting+        , ratchet -          -- * Padding-        , padForward+          -- * Chain operators+        , unchainToVector+        , unchainToMVector -          -- * Scanning-        , scanMaybe+          -- ** Folding+        , folds, C.Folds(..) -          -- * Grouping+          -- ** Scanning+        , scanMaybe         , groupsBy -          -- * Folding-        , folds, C.Folds(..))+          -- ** Conversion+        , chainOfVector+        ) where-import Data.Repa.Option import Data.Vector.Unboxed                              (Unbox, Vector) import Data.Vector.Unboxed.Mutable                      (MVector) import Data.Repa.Chain                                  (Chain)+import Data.Repa.Scalar.Option import qualified Data.Repa.Vector.Generic               as G import qualified Data.Repa.Chain                        as C import qualified Data.Vector.Unboxed                    as U@@ -257,7 +259,7 @@ -- compact         :: (Unbox a, Unbox b)-        => (s -> a -> (Maybe b, s))     -- ^ Worker function+        => (s -> a -> (s, Maybe b))     -- ^ Worker function         -> s                            -- ^ Starting state         -> Vector a                     -- ^ Input vector         -> Vector b@@ -270,7 +272,7 @@ --   initial state, and add the final state to the end of the output. compactIn         :: Unbox a-        => (a -> a -> (Maybe a, a))     -- ^ Worker function.+        => (a -> a -> (a, Maybe a))     -- ^ Worker function.         -> Vector a                     -- ^ Input elements.         -> Vector a 
repa-stream.cabal view
@@ -1,5 +1,5 @@ Name:           repa-stream-Version:        4.1.0.1+Version:        4.2.2.1 License:        BSD3 License-file:   LICENSE Author:         The Repa Development Team@@ -19,14 +19,14 @@  Library   build-Depends: -        base            == 4.7.*,+        base            == 4.8.*,         vector          == 0.10.*,-        primitive       == 0.5.4.*,-        mtl             == 2.2.*+        primitive       == 0.6.*,+        mtl             == 2.2.*,+        repa-scalar     == 4.2.2.*    exposed-modules:         Data.Repa.Chain-        Data.Repa.Option         Data.Repa.Stream         Data.Repa.Vector.Generic         Data.Repa.Vector.Unboxed@@ -46,6 +46,7 @@         Data.Repa.Stream.Merge         Data.Repa.Stream.Pad         Data.Repa.Stream.Ratchet+        Data.Repa.Stream.Replicate         Data.Repa.Stream.Segment    include-dirs: