Browse Source

Adds intercalateAction

Marcos Dumay de Medeiros 7 years ago
parent
commit
1287744c37
2 changed files with 25 additions and 3 deletions
  1. 1 1
      interruptible.cabal
  2. 24 2
      src/Control/Monad/Trans/Interruptible.hs

+ 1 - 1
interruptible.cabal

@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                interruptible
-version:             0.1.1.1
+version:             0.1.2.0
 synopsis:            Monad transformers that can be run and resumed later, conserving their context.
 description:
     This package provides the functionality needed to intercalate the execution of different

+ 24 - 2
src/Control/Monad/Trans/Interruptible.hs

@@ -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