module Piped.Resume
( createResumableSource
, createResumableSink
, runResumableSource
, runResumableSink
, ResumableSource(..)
, ResumableSink(..)
, ResumableResult(..)
) where
import Piped.Internal
data ResumableResult e m a b =
ResumeSource (ResumableSource e m a b) b
| ResumeSink (ResumableSink e m a b) a
newtype ResumableSource o m a b = ResumableSource (Await o m (ResumableResult o m a b))
newtype ResumableSink i m a b = ResumableSink (Yield i m (ResumableResult i m a b))
createResumableSource :: Monad m => Pipe () o m a -> ResumableSource o m a b
createResumableSource (Pipe f) = ResumableSource $
Await $ f (\l r a -> pure $ ResumeSink (ResumableSink r) a) termLeft
createResumableSink :: Monad m => Pipe i Void m b -> ResumableSink i m a b
createResumableSink (Pipe f) = ResumableSink $
Yield
( f resumeLeft termLeft voidRight)
(\i left -> f resumeLeft (addLeftover i left) voidRight)
where
resumeLeft l _ b = pure $ ResumeSource (ResumableSource l) b
runResumableSource :: Monad m => ResumableSource i m a b -> Pipe i Void m b -> m (ResumableResult i m a b)
runResumableSource (ResumableSource source) (Pipe f) =
f (\l _ b -> pure $ ResumeSource (ResumableSource l) b) source voidRight
runResumableSink :: Monad m => Pipe () o m a -> ResumableSink o m a b -> m (ResumableResult o m a b)
runResumableSink (Pipe f) (ResumableSink sink) =
f (\_ r a -> pure $ ResumeSink (ResumableSink r) a) termLeft sink