module Bio.Streaming.Furrow
( Furrow(..)
, evertStream
, afford
, drain
) where
import Bio.Prelude
import Bio.Streaming
newtype Furrow a m r = Furrow (Stream ((->) (Maybe a)) m r) deriving
(Functor, Applicative, Monad, MonadTrans, MonadIO, MFunctor, MMonad)
instance MonadThrow m => MonadThrow (Furrow a m) where
throwM = Furrow . lift . throwM
afford :: Monad m => Furrow a m b -> a -> m (Furrow a m b)
afford (Furrow s) a = inspect s >>= \case
Left b -> return (Furrow (pure b))
Right f -> return (Furrow (f (Just a)))
drain :: Monad m => Furrow a m b -> m b
drain (Furrow s) = inspect s >>= \case
Left b -> return b
Right f -> inspect (f Nothing) >>= \case
Left b -> return b
Right _ -> error "continuedAfterEOF"
evertStream :: Monad m => (Stream (Of a) (Furrow a m) () -> Furrow a m b) -> Furrow a m b
evertStream consumer = consumer cat
where
cat = lift (Furrow (yields id)) >>= maybe (pure ()) (\a -> wrap (a :> cat))