repa-flow-4.0.0.1: Data/Repa/Flow/Generic/Map.hs
module Data.Repa.Flow.Generic.Map
( map_i, map_o
, smap_i, smap_o
, szipWith_ii, szipWith_io, szipWith_oi)
where
import Data.Repa.Flow.Generic.Base
import Control.Monad
import Prelude as P
#include "repa-flow.h"
-- | Apply a function to every element pulled from some sources,
-- producing some new sources.
map_i :: Monad m
=> (a -> b) -> Sources i m a -> m (Sources i m b)
map_i f s = smap_i (\_ x -> f x) s
{-# INLINE map_i #-}
-- | Like `map_i`, but the worker function is also given the stream index.
smap_i :: Monad m
=> (i -> a -> b) -> Sources i m a -> m (Sources i m b)
smap_i f (Sources n pullsA)
= return $ Sources n pullsB_map
where
pullsB_map i eat eject
= pullsA i eat_a eject_a
where
eat_a v = eat (f i v)
{-# INLINE eat_a #-}
eject_a = eject
{-# INLINE eject_a #-}
{-# INLINE [1] pullsB_map #-}
{-# INLINE_FLOW smap_i #-}
-- | Apply a function to every element pulled from some sources,
-- producing some new sources.
map_o :: Monad m
=> (a -> b) -> Sinks i m b -> m (Sinks i m a)
map_o f k = smap_o (\_ x -> f x) k
{-# INLINE map_o #-}
-- | Like `map_o`, but the worker function is also given the stream index.
smap_o :: Monad m
=> (i -> a -> b) -> Sinks i m b -> m (Sinks i m a)
smap_o f (Sinks n pushB ejectB)
= return $ Sinks n pushA_map ejectA_map
where
pushA_map i a = pushB i (f i a)
{-# INLINE pushA_map #-}
ejectA_map i = ejectB i
{-# INLINE ejectA_map #-}
{-# INLINE_FLOW smap_o #-}
-- | Combine the elements of two flows with the given function.
-- The worker function is also given the stream index.
szipWith_ii
:: (Ord i, Monad m)
=> (i -> a -> b -> c)
-> Sources i m a -> Sources i m b
-> m (Sources i m c)
szipWith_ii f (Sources nA pullA) (Sources nB pullB)
= return $ Sources (min nA nB) pull_szipWith
where
pull_szipWith i eat eject
= pullA i eatA eject
where
eatA xA = pullB i eatB eject
where
eatB xB = eat (f i xA xB)
{-# INLINE eatB #-}
{-# INLINE eatA #-}
{-# INLINE pull_szipWith #-}
{-# INLINE_FLOW szipWith_ii #-}
-- | Like `szipWith_ii`, but take a bundle of `Sinks` for the result
-- elements, and yield a bundle of `Sinks` to accept the @b@ elements.
szipWith_io
:: (Ord i, Monad m)
=> (i -> a -> b -> c)
-> Sinks i m c -> Sources i m a
-> m (Sinks i m b)
szipWith_io f (Sinks nC pushC ejectC) (Sources nA pullA)
= return $ Sinks nB pushB ejectC
where
!nB = min nC nA
pushB i xB
| i > nB = return ()
| otherwise = pullA i eatA (ejectC i)
where
eatA xA = pushC i (f i xA xB)
{-# INLINE eatA #-}
{-# INLINE pushB #-}
{-# INLINE_FLOW szipWith_io #-}
-- | Like `szipWith_ii`, but take a bundle of `Sinks` for the result
-- elements, and yield a bundle of `Sinks` to accept the @a@ elements.
szipWith_oi
:: (Ord i, Monad m)
=> (i -> a -> b -> c)
-> Sinks i m c -> Sources i m b
-> m (Sinks i m a)
szipWith_oi f (Sinks nC pushC ejectC) (Sources nB pullB)
= return $ Sinks nA pushA ejectC
where
!nA = min nC nB
pushA i xA
| i > nA = return ()
| otherwise = pullB i eatB (ejectC i)
where
eatB xB = pushC i (f i xA xB)
{-# INLINE eatB #-}
{-# INLINE pushA #-}
{-# INLINE_FLOW szipWith_oi #-}