|
@@ -3,7 +3,8 @@
|
|
|
module Control.Monad.Trans.Interruptible (
|
|
|
module Control.Monad.Trans.Interruptible.Class,
|
|
|
-- * Interruptible applications
|
|
|
- intercalateWith
|
|
|
+ intercalateWith,
|
|
|
+ intercalateAction
|
|
|
)where
|
|
|
|
|
|
import Control.Monad.Trans.Interruptible.Class
|
|
@@ -13,7 +14,7 @@ Folds the second list with the function applied to the first,
|
|
|
intercalating the evaluation. That is:
|
|
|
|
|
|
@
|
|
|
-intercalateWith resume f [a00, a10, a20] [b1, b2] = do
|
|
|
+intercalateWith resume f [b1, b2] [a00, a10, a20] = do
|
|
|
a01 <- resume (f b1) a00
|
|
|
a11 <- resume (f b1) a10
|
|
|
a21 <- resume (f b1) a20
|
|
@@ -33,3 +34,24 @@ 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
|