module Data.Repa.Flow.Generic.List ( fromList , toList1 , takeList1 , pushList , pushList1) where import Data.Repa.Flow.Generic.Base #include "repa-flow.h" ------------------------------------------------------------------------------- -- | Given an arity and a list of elements, yield sources that each produce -- all the elements. fromList :: States i m => i -> [a] -> m (Sources i m a) fromList n xx0 = do refs <- newRefs n xx0 let pull_fromList i eat eject = do xx <- readRefs refs i case xx of [] -> eject x : xs -> do writeRefs refs i xs eat x {-# INLINE pull_fromList #-} return $ Sources n pull_fromList {-# INLINE_FLOW fromList #-} -- | Drain a single source into a list. toList1 :: States i m => i -> Sources i m a -> m [a] toList1 i (Sources n pullX) = do refs <- newRefs n [] let loop_toList !acc = pullX i eat_toList eject_toList where eat_toList x = loop_toList (x : acc) eject_toList = writeRefs refs i (reverse acc) {-# INLINE loop_toList #-} loop_toList [] xx <- readRefs refs i return xx {-# INLINE_FLOW toList1 #-} -- | Drain the given number of elements from a single source into a list. takeList1 :: States i m => Int -> i -> Sources i m a -> m [a] takeList1 len i (Sources n pullX) = do refs <- newRefs n [] let loop_toList !ix !acc | ix >= len = writeRefs refs i (reverse acc) | otherwise = pullX i eat_toList eject_toList where eat_toList x = loop_toList (ix + 1) (x : acc) eject_toList = writeRefs refs i (reverse acc) {-# INLINE loop_toList #-} loop_toList 0 [] xx <- readRefs refs i return xx {-# INLINE_FLOW takeList1 #-} ------------------------------------------------------------------------------- -- | Push elements into the associated streams of a bundle of sinks. pushList :: Monad m => [(i, a)] -> Sinks i m a -> m () pushList xx (Sinks _nSinks eat _eject) = loop_pushList xx where loop_pushList [] = return () loop_pushList ((i, x) : ixs) = do eat i x loop_pushList ixs {-# INLINE_FLOW pushList #-} -- | Push the elements of a list into the given stream of a -- bundle of sinks. pushList1 :: Monad m => i -> [a] -> Sinks i m a -> m () pushList1 i xx (Sinks _nSinks eat _eject) = loop_pushList1 xx where loop_pushList1 [] = return () loop_pushList1 (x : xs) = do eat i x loop_pushList1 xs {-# INLINE_FLOW pushList1 #-}