monad-extras 0.4.0.0 → 0.5.0
raw patch · 2 files changed
+122/−3 lines, 2 filesdep +monad-control
Dependencies added: monad-control
Files
- Control/Monad/Extra.hs +120/−2
- monad-extras.cabal +2/−1
Control/Monad/Extra.hs view
@@ -1,9 +1,13 @@+{-# LANGUAGE FlexibleContexts #-}+ module Control.Monad.Extra where import Control.Applicative import Control.Monad-import Control.Monad.Trans.Cont import Control.Monad.IO.Class+import Control.Monad.Trans.Cont+import Control.Monad.Trans.Control+import Data.IORef -- | Synonym for @return ()@. skip :: Monad m => m ()@@ -63,5 +67,119 @@ io = liftIO -- | Lift a 'Maybe' value into the 'MaybeT' monad transformer.-liftMaybe :: (MonadPlus m) => Maybe a -> m a+liftMaybe :: MonadPlus m => Maybe a -> m a liftMaybe = maybe mzero return++-- | Embed a transformer (Kleisli) arrow as an arrow in the base monad+-- returning a mutated transformer state. If you do not want the+-- transformation and your base monad is IO, use 'embedIO'.+embed :: (MonadBaseControl base m) => (a -> m b) -> m (a -> base (StM m b))+embed f = control $ \run -> run $ return (run . f)++-- | Return an IO action that closes over the current monad transformer, but+-- throws away any residual effects within that transformer.+embedIO :: (MonadBaseControl IO m, MonadIO m) => (a -> m b) -> m (a -> IO b)+embedIO f = liftBaseWith $ \run -> do+ result <- newIORef undefined+ return $ \a -> do+ _ <- run $ do+ res <- f a+ liftIO $ writeIORef result res+ readIORef result++embedIO2 :: (MonadBaseControl IO m, MonadIO m)+ => (a -> b -> m r) -> m (a -> b -> IO r)+embedIO2 f = liftBaseWith $ \run -> do+ result <- newIORef undefined+ return $ \a b -> do+ _ <- run $ do+ res <- f a b+ liftIO $ writeIORef result res+ readIORef result++embedIO3 :: (MonadBaseControl IO m, MonadIO m)+ => (a -> b -> c -> m r) -> m (a -> b -> c -> IO r)+embedIO3 f = liftBaseWith $ \run -> do+ result <- newIORef undefined+ return $ \a b c -> do+ _ <- run $ do+ res <- f a b c+ liftIO $ writeIORef result res+ readIORef result++embedIO4 :: (MonadBaseControl IO m, MonadIO m)+ => (a -> b -> c -> d -> m r) -> m (a -> b -> c -> d -> IO r)+embedIO4 f = liftBaseWith $ \run -> do+ result <- newIORef undefined+ return $ \a b c d -> do+ _ <- run $ do+ res <- f a b c d+ liftIO $ writeIORef result res+ readIORef result++embedIO5 :: (MonadBaseControl IO m, MonadIO m)+ => (a -> b -> c -> d -> e -> m r) -> m (a -> b -> c -> d -> e -> IO r)+embedIO5 f = liftBaseWith $ \run -> do+ result <- newIORef undefined+ return $ \a b c d e -> do+ _ <- run $ do+ res <- f a b c d e+ liftIO $ writeIORef result res+ readIORef result++embedIO6 :: (MonadBaseControl IO m, MonadIO m)+ => (a -> b -> c -> d -> e -> f -> m r)+ -> m (a -> b -> c -> d -> e -> f -> IO r)+embedIO6 x = liftBaseWith $ \run -> do+ result <- newIORef undefined+ return $ \a b c d e f -> do+ _ <- run $ do+ res <- x a b c d e f+ liftIO $ writeIORef result res+ readIORef result++embedIO7 :: (MonadBaseControl IO m, MonadIO m)+ => (a -> b -> c -> d -> e -> f -> g -> m r)+ -> m (a -> b -> c -> d -> e -> f -> g -> IO r)+embedIO7 x = liftBaseWith $ \run -> do+ result <- newIORef undefined+ return $ \a b c d e f g -> do+ _ <- run $ do+ res <- x a b c d e f g+ liftIO $ writeIORef result res+ readIORef result++embedIO8 :: (MonadBaseControl IO m, MonadIO m)+ => (a -> b -> c -> d -> e -> f -> g -> h -> m r)+ -> m (a -> b -> c -> d -> e -> f -> g -> h -> IO r)+embedIO8 x = liftBaseWith $ \run -> do+ result <- newIORef undefined+ return $ \a b c d e f g h -> do+ _ <- run $ do+ res <- x a b c d e f g h+ liftIO $ writeIORef result res+ readIORef result++embedIO9 :: (MonadBaseControl IO m, MonadIO m)+ => (a -> b -> c -> d -> e -> f -> g -> h -> i -> m r)+ -> m (a -> b -> c -> d -> e -> f -> g -> h -> i -> IO r)+embedIO9 x = liftBaseWith $ \run -> do+ result <- newIORef undefined+ return $ \a b c d e f g h i -> do+ _ <- run $ do+ res <- x a b c d e f g h i+ liftIO $ writeIORef result res+ readIORef result++-- | Draw monadic actions from a list until one of them yields a value failing+-- the predicate, and then return all the passing values in a list within+-- that monad.+sequenceUntil :: Monad m => (a -> Bool) -> [m a] -> m [a]+sequenceUntil _ [] = return []+sequenceUntil p (m:ms) = do+ a <- m+ if p a+ then return [a]+ else do+ as <- sequenceUntil p ms+ return (a:as)
monad-extras.cabal view
@@ -1,5 +1,5 @@ name: monad-extras-version: 0.4.0.0+version: 0.5.0 synopsis: Extra utility functions for working with monads -- description: homepage: http://github.com/jwiegley/monad-extras@@ -18,4 +18,5 @@ Control.Monad.Extra build-depends: base >= 4 && < 5+ , monad-control , transformers