module Data.Conduit.List
(
sourceList
, sourceNull
, fold
, take
, drop
, head
, peek
, consume
, sinkNull
, foldM
, mapM_
, map
, concatMap
, concatMapAccum
, groupBy
, isolate
, filter
, mapM
, concatMapM
, concatMapAccumM
) where
import Prelude
( ($), return, (==), (), Int
, (.), id, Maybe (..), fmap, Monad
, Bool (..)
, (>>)
)
import qualified Prelude
import Data.Conduit
import Control.Monad.Trans.Class (lift)
import Data.Monoid (mempty)
fold :: Resource m
=> (b -> a -> b)
-> b
-> Sink a m b
fold f accum0 = sinkState
accum0
(\accum input -> return (StateProcessing $ f accum input))
return
foldM :: Resource m
=> (b -> a -> m b)
-> b
-> Sink a m b
foldM f accum0 = sinkState
accum0
(\accum input -> do
accum' <- lift $ f accum input
return $ StateProcessing accum'
)
return
mapM_ :: Resource m
=> (a -> m ())
-> Sink a m ()
mapM_ f =
SinkData push close
where
push input = lift (f input) >> return (Processing push close)
close = return ()
sourceList :: Resource m => [a] -> Source m a
sourceList l0 =
sourceState l0 go
where
go [] = return StateClosed
go (x:xs) = return $ StateOpen xs x
drop :: Resource m
=> Int
-> Sink a m ()
drop count0 = sinkState
count0
push
close
where
push 0 x = return $ StateDone (Just x) ()
push count _ = do
let count' = count 1
return $ if count' == 0
then StateDone Nothing ()
else StateProcessing count'
close _ = return ()
take :: Resource m
=> Int
-> Sink a m [a]
take count0 = sinkState
(count0, id)
push
close
where
push (0, front) x = return (StateDone (Just x) (front []))
push (count, front) x = do
let count' = count 1
front' = front . (x:)
return $ if count' == 0
then StateDone Nothing (front' [])
else StateProcessing (count', front')
close (_, front) = return $ front []
head :: Resource m => Sink a m (Maybe a)
head =
SinkData push close
where
push x = return $ Done Nothing (Just x)
close = return Nothing
peek :: Resource m => Sink a m (Maybe a)
peek =
SinkData push close
where
push x = return $ Done (Just x) (Just x)
close = return Nothing
map :: Monad m => (a -> b) -> Conduit a m b
map f =
conduit
where
conduit = Conduit push close
push = return . Producing conduit . return . f
close = return []
mapM :: Monad m => (a -> m b) -> Conduit a m b
mapM f =
conduit
where
conduit = Conduit push close
push = fmap (Producing conduit . return) . lift . f
close = return []
concatMap :: Monad m => (a -> [b]) -> Conduit a m b
concatMap f =
conduit
where
conduit = Conduit push close
push = return . Producing conduit . f
close = return []
concatMapM :: Monad m => (a -> m [b]) -> Conduit a m b
concatMapM f =
conduit
where
conduit = Conduit push close
push = fmap (Producing conduit) . lift . f
close = return []
concatMapAccum :: Resource m => (a -> accum -> (accum, [b])) -> accum -> Conduit a m b
concatMapAccum f accum = conduitState accum push close
where
push state input = let (state', result) = f input state
in return $ StateProducing state' result
close _ = return []
concatMapAccumM :: Resource m => (a -> accum -> m (accum, [b])) -> accum -> Conduit a m b
concatMapAccumM f accum = conduitState accum push close
where
push state input = do (state', result) <- lift (f input state)
return $ StateProducing state' result
close _ = return []
consume :: Resource m => Sink a m [a]
consume = sinkState
id
(\front input -> return (StateProcessing $ front . (input :)))
(\front -> return $ front [])
groupBy :: Resource m => (a -> a -> Bool) -> Conduit a m [a]
groupBy f = conduitState
[]
push
close
where
push [] v = return $ StateProducing [v] []
push s@(x:_) v =
if f x v then
return $ StateProducing (v:s) []
else
return $ StateProducing [v] [s]
close s = return [s]
isolate :: Resource m => Int -> Conduit a m a
isolate count0 = conduitState
count0
push
close
where
close _ = return []
push count x = do
if count == 0
then return $ StateFinished (Just x) []
else do
let count' = count 1
return $ if count' == 0
then StateFinished Nothing [x]
else StateProducing count' [x]
filter :: Resource m => (a -> Bool) -> Conduit a m a
filter f =
conduit
where
conduit = Conduit push close
push = return . Producing conduit . Prelude.filter f . return
close = return []
sinkNull :: Resource m => Sink a m ()
sinkNull =
SinkData push close
where
push _ = return $ Processing push close
close = return ()
sourceNull :: Resource m => Source m a
sourceNull = mempty