module Data.Repa.Flow.Auto.Base ( Sources , Sinks , Flow , sourcesArity , sinksArity -- * Conversion -- ** List conversion , fromList, fromLists , toList1, toLists1 -- ** Array conversion , fromArray, fromArrays , toArray1, toArrays1) where import Data.Repa.Array.Auto hiding (fromList, fromLists) import Data.Repa.Array.Material.Auto (A(..), Name(..)) import qualified Data.Repa.Flow.Chunked as C import qualified Data.Repa.Flow.Generic as G import qualified Data.Repa.Array.Meta.Window as A import qualified Data.Repa.Array.Auto as A #include "repa-flow.h" -- | A bundle of stream sources, where the elements of the stream -- are chunked into arrays. type Sources a = C.Sources Int IO A a -- | A bundle of stream sinks, where the elements of the stream -- are chunked into arrays. -- type Sinks a = C.Sinks Int IO A a -- | Shorthand for common type classes. type Flow a = (C.Flow Int IO A a, A.Windowable A a) -- | Yield the number of streams in the bundle. sourcesArity :: Sources a -> Int sourcesArity = G.sourcesArity {-# INLINE_FLOW sourcesArity #-} -- | Yield the number of streams in the bundle. sinksArity :: Sinks a -> Int sinksArity = G.sinksArity {-# INLINE_FLOW sinksArity #-} -- Conversion ----------------------------------------------------------------- -- | Given an arity and a list of elements, -- yield sources that each produce all the elements. -- -- * All elements are stuffed into a single chunk, -- and each stream is given the same chunk. -- fromList :: Build a => Int -> [a] -> IO (Sources a) fromList xs = C.fromList A xs {-# INLINE_FLOW fromList #-} -- | Like `fromList` but take a list of lists. -- Each each of the inner lists is packed into a single chunk. fromLists :: Build a => Int -> [[a]] -> IO (Sources a) fromLists xss = C.fromLists A xss {-# INLINE_FLOW fromLists #-} -- | Drain a single source from a bundle into a list of elements. -- -- * If the index does not specify a valid stream then the result will -- be empty. -- toList1 :: Build a => Int -> Sources a -> IO [a] toList1 ix s | ix < 0 || ix >= G.sourcesArity s = return [] | otherwise = C.toList1 ix s {-# INLINE_FLOW toList1 #-} -- | Drain a single source from a bundle into a list of chunks. -- -- * If the index does not specify a valid stream then the result will -- be empty. -- toLists1 :: Build a => Int -> Sources a -> IO [[a]] toLists1 ix s | ix < 0 || ix >= G.sourcesArity s = return [] | otherwise = C.toLists1 ix s {-# INLINE_FLOW toLists1 #-} ------------------------------------------------------------------------------- -- | Given an arity and an array of elements, -- yield sources that each produce all the elements. -- -- * All elements are stuffed into a single chunk, -- and each stream is given the same chunk. -- fromArray :: Build a => Int -> Array a -> IO (Sources a) fromArray n arr = G.fromList n [arr] {-# INLINE_FLOW fromArray #-} -- | Like `fromArray` but take an array of arrays. -- Each of the inner arrays is packed into a single chunk. fromArrays :: (Elem a, Build a) => Int -> Array (Array a) -> IO (Sources a) fromArrays n arrs = G.fromList n (A.toList arrs) {-# INLINE_FLOW fromArrays #-} -- | Drain a single source from a bundle into an array of elements. -- -- * If the index does not specify a valid stream then the result will -- be empty. -- toArray1 :: (Elem a, Build a) => Int -> Sources a -> IO (Array a) toArray1 ix ss | ix < 0 || ix >= G.sourcesArity ss = return $ A.fromList [] | otherwise = do chunks <- G.toList1 ix ss return $ A.concat $ A.fromList chunks {-# INLINE_FLOW toArray1 #-} -- | Drain a single source from a bundle into an array of elements. -- -- * If the index does not specify a valid stream then the result will -- be empty. -- toArrays1 :: (Elem a, Build a) => Int -> Sources a -> IO (Array (Array a)) toArrays1 ix ss | ix < 0 || ix >= G.sourcesArity ss = return $ A.fromList [] | otherwise = do chunks <- G.toList1 ix ss return $ A.fromList chunks {-# INLINE_FLOW toArrays1 #-}