module Stream (
Stream(..), yield, liftIO,
collect, collect_, consume, fromList,
Stream.map, Stream.mapM, Stream.mapAccumL, Stream.mapAccumL_
) where
import GhcPrelude
import Control.Monad
newtype Stream m a b = Stream { runStream :: m (Either b (a, Stream m a b)) }
instance Monad f => Functor (Stream f a) where
fmap = liftM
instance Monad m => Applicative (Stream m a) where
pure a = Stream (return (Left a))
(<*>) = ap
instance Monad m => Monad (Stream m a) where
Stream m >>= k = Stream $ do
r <- m
case r of
Left b -> runStream (k b)
Right (a,str) -> return (Right (a, str >>= k))
yield :: Monad m => a -> Stream m a ()
yield a = Stream (return (Right (a, return ())))
liftIO :: IO a -> Stream IO b a
liftIO io = Stream $ io >>= return . Left
collect :: Monad m => Stream m a () -> m [a]
collect str = go str []
where
go str acc = do
r <- runStream str
case r of
Left () -> return (reverse acc)
Right (a, str') -> go str' (a:acc)
collect_ :: Monad m => Stream m a r -> m ([a], r)
collect_ str = go str []
where
go str acc = do
r <- runStream str
case r of
Left r -> return (reverse acc, r)
Right (a, str') -> go str' (a:acc)
consume :: Monad m => Stream m a b -> (a -> m ()) -> m b
consume str f = do
r <- runStream str
case r of
Left ret -> return ret
Right (a, str') -> do
f a
consume str' f
fromList :: Monad m => [a] -> Stream m a ()
fromList = mapM_ yield
map :: Monad m => (a -> b) -> Stream m a x -> Stream m b x
map f str = Stream $ do
r <- runStream str
case r of
Left x -> return (Left x)
Right (a, str') -> return (Right (f a, Stream.map f str'))
mapM :: Monad m => (a -> m b) -> Stream m a x -> Stream m b x
mapM f str = Stream $ do
r <- runStream str
case r of
Left x -> return (Left x)
Right (a, str') -> do
b <- f a
return (Right (b, Stream.mapM f str'))
mapAccumL :: Monad m => (c -> a -> m (c,b)) -> c -> Stream m a ()
-> Stream m b c
mapAccumL f c str = Stream $ do
r <- runStream str
case r of
Left () -> return (Left c)
Right (a, str') -> do
(c',b) <- f c a
return (Right (b, mapAccumL f c' str'))
mapAccumL_ :: Monad m => (c -> a -> m (c,b)) -> c -> Stream m a r
-> Stream m b (c, r)
mapAccumL_ f c str = Stream $ do
r <- runStream str
case r of
Left r -> return (Left (c, r))
Right (a, str') -> do
(c',b) <- f c a
return (Right (b, mapAccumL_ f c' str'))