123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- {-# LANGUAGE TypeFamilies #-}
- module Control.Monad.Trans.Interruptible (
- module Control.Monad.Trans.Interruptible.Class,
- -- * Interruptible applications
- intercalateWith,
- intercalateAction
- )where
- import Control.Monad.Trans.Interruptible.Class
- {- |
- Folds the second list with the function applied to the first,
- intercalating the evaluation. That is:
- @
- intercalateWith resume f [b1, b2] [a00, a10, a20] = do
- a01 <- resume (f b1) a00
- a11 <- resume (f b1) a10
- a21 <- resume (f b1) a20
- a02 <- resume (f b2) a11
- a12 <- resume (f b2) a21
- a22 <- resume (f b2) a31
- return [a02, a12, a22]
- @
- Usefull for consuming lazy sequences.
- The resume function is parametric for allowing resuming deeper Interruptible chains, with
- resume2, resume3, etc.
- -}
- intercalateWith :: Monad m => ((a -> t a) -> rsta -> m (rsta)) -> (b -> a -> t a) -> [b] -> [rsta] -> m [rsta]
- intercalateWith _ _ [] aa = return aa
- intercalateWith res f (b:bb) aa = do
- aa' <- mapM (res $ f b) aa
- intercalateWith res f bb aa'
- {- |
- Intercalates the execution of the function, on the interrupted contexts given, but instead of
- folding them over a list like "intercalateWith", it folds them on the result of the monadic
- action untill it returns Nothing.
- That is, if @get@ is a monadic action that when repeated called returns @Just "a"@, @Just "b"@,
- @Just "c"@ and @Nothing@, those two lines are equivalent:
- > intercalateWith resume f ["a", "b", "c"] ctxs
- > intercalateAction resume f get ctxs
- IntercalateAction can intercalate contexts over non-lazy IO.
- -}
- intercalateAction :: Monad m => ((a -> t a) -> rsta -> m (rsta)) -> (b -> a -> t a) -> m (Maybe b) -> [rsta] -> m [rsta]
- intercalateAction res f get ctx = do
- v' <- get
- case v' of
- Nothing -> return ctx
- Just v -> mapM (res $ f v) ctx >>= intercalateAction res f get
|