Skip to content

Commit

Permalink
stream: add segmented unfold operation
Browse files Browse the repository at this point in the history
  • Loading branch information
benl23x5 committed Mar 13, 2016
1 parent b12c63f commit 4da20a9
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
3 changes: 3 additions & 0 deletions repa-stream/Data/Repa/Chain.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ module Data.Repa.Chain
-- * Folding
, foldsC, Folds(..)

-- * Unfolding
, unfoldsC

-- * Scanning
, scanMaybeC

Expand Down
42 changes: 41 additions & 1 deletion repa-stream/Data/Repa/Chain/Scan.hs
Original file line number Diff line number Diff line change
@@ -1,13 +1,53 @@

module Data.Repa.Chain.Scan
( scanMaybeC
( unfoldsC
, scanMaybeC
, groupsByC)
where
import Data.Repa.Chain.Base
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 (k, Maybe b)) -- ^ Worker function.
-> k -- ^ Initial state for the unfold.
-> Chain m s a -- ^ Input elements.
-> Chain m (s, k, Maybe a) b -- ^ Output elements.

unfoldsC f k0 (Chain _ s0 istep)
= Chain S.Unknown (s0, k0, Nothing) ostep
where
ostep (s1, k1, Nothing)
= istep s1 >>= \rs
-> case rs of
Yield xa s2 -> return $ Skip (s2, k1, Just xa)
Skip s2 -> return $ Skip (s2, k1, Nothing)
Done s2 -> return $ Done (s2, k1, Nothing)

ostep (s1, k1, Just xa)
= f xa k1 >>= \kmb
-> case kmb of
(k2, Nothing) -> return $ Skip (s1, k2, Nothing)
(k2, Just xb) -> return $ Yield xb (s1, k2, Just xa)
{-# INLINE_INNER ostep #-}
{-# INLINE_STREAM unfoldsC #-}


-------------------------------------------------------------------------------
-- | 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
Expand Down

0 comments on commit 4da20a9

Please sign in to comment.