| Safe Haskell | Safe-Inferred |
|---|
Control.Monad.MultiWrap
Contents
MultiWrap class
class Monad mOut => MultiWrap mIn mOut a r | mIn mOut a -> r whereSource
MultiWrap is like MonadWrapIO, but for monads created by
MonadTrans transformers. This is useful, if, for example, you
implement your own monad, ReaderTLike, that is like a ReaderT
except that you don't want to make it a member of the MonadReader
class because you are already using MonadReader for some
different state (or because you are implementing a library and the
user of the library should be free to use ReaderT).
As long as ReaderTLike is a member of the MonadTrans class and
assuming you have a localLike function equivalent to local, you
should be able to run things like:
mwrap (localLike modifyConfig :: ReaderTLike IO a -> ReaderTLike IO a)
someComputation
You will generally have to specify the type of the wrap function or
computation explicitly, but as long as you specify the type,
mwrap saves you from keeping track of how many nested levels of
transformer you have and from having to invoke wrap repeatedly.
Note one difference from MonadWrap and MonadWrapIO is that
mresult and mresultF require an extra argument so as to specify
the inner monad in which you want to supply the result. (E.g., in
the case of using catch to produce a different return value in
case of exceptions, the inner monad would be IO, and the extra
argument might be supplied as (undefined :: .
IO Type)
Note that MultiWrap only works for up to 9 levels of nested
monad transformer.
Methods
mwrap :: (mIn r -> mIn r) -> mOut a -> mOut aSource
Arguments
| :: mIn b | This argument is here just for the type, because
otherwise the |
| -> mOut (a -> r) |
Instances
| Monad m => MultiWrap m m a a | |
| (MonadTrans t9, Monad (t9 (t8 (t7 (t6 (t5 (t4 (t3 (t2 (t1 m))))))))), MonadWrap t9 a9 a8, MonadTrans t8, Monad (t8 (t7 (t6 (t5 (t4 (t3 (t2 (t1 m)))))))), MonadWrap t8 a8 a7, MonadTrans t7, Monad (t7 (t6 (t5 (t4 (t3 (t2 (t1 m))))))), MonadWrap t7 a7 a6, MonadTrans t6, Monad (t6 (t5 (t4 (t3 (t2 (t1 m)))))), MonadWrap t6 a6 a5, MonadTrans t5, Monad (t5 (t4 (t3 (t2 (t1 m))))), MonadWrap t5 a5 a4, MonadTrans t4, Monad (t4 (t3 (t2 (t1 m)))), MonadWrap t4 a4 a3, MonadTrans t3, Monad (t3 (t2 (t1 m))), MonadWrap t3 a3 a2, MonadTrans t2, Monad (t2 (t1 m)), MonadWrap t2 a2 a1, MonadTrans t1, Monad (t1 m), MonadWrap t1 a1 a0, Monad m) => MultiWrap m (t9 (t8 (t7 (t6 (t5 (t4 (t3 (t2 (t1 m))))))))) a9 a0 | |
| (MonadTrans t8, Monad (t8 (t7 (t6 (t5 (t4 (t3 (t2 (t1 m)))))))), MonadWrap t8 a8 a7, MonadTrans t7, Monad (t7 (t6 (t5 (t4 (t3 (t2 (t1 m))))))), MonadWrap t7 a7 a6, MonadTrans t6, Monad (t6 (t5 (t4 (t3 (t2 (t1 m)))))), MonadWrap t6 a6 a5, MonadTrans t5, Monad (t5 (t4 (t3 (t2 (t1 m))))), MonadWrap t5 a5 a4, MonadTrans t4, Monad (t4 (t3 (t2 (t1 m)))), MonadWrap t4 a4 a3, MonadTrans t3, Monad (t3 (t2 (t1 m))), MonadWrap t3 a3 a2, MonadTrans t2, Monad (t2 (t1 m)), MonadWrap t2 a2 a1, MonadTrans t1, Monad (t1 m), MonadWrap t1 a1 a0, Monad m) => MultiWrap m (t8 (t7 (t6 (t5 (t4 (t3 (t2 (t1 m)))))))) a8 a0 | |
| (MonadTrans t7, Monad (t7 (t6 (t5 (t4 (t3 (t2 (t1 m))))))), MonadWrap t7 a7 a6, MonadTrans t6, Monad (t6 (t5 (t4 (t3 (t2 (t1 m)))))), MonadWrap t6 a6 a5, MonadTrans t5, Monad (t5 (t4 (t3 (t2 (t1 m))))), MonadWrap t5 a5 a4, MonadTrans t4, Monad (t4 (t3 (t2 (t1 m)))), MonadWrap t4 a4 a3, MonadTrans t3, Monad (t3 (t2 (t1 m))), MonadWrap t3 a3 a2, MonadTrans t2, Monad (t2 (t1 m)), MonadWrap t2 a2 a1, MonadTrans t1, Monad (t1 m), MonadWrap t1 a1 a0, Monad m) => MultiWrap m (t7 (t6 (t5 (t4 (t3 (t2 (t1 m))))))) a7 a0 | |
| (MonadTrans t6, Monad (t6 (t5 (t4 (t3 (t2 (t1 m)))))), MonadWrap t6 a6 a5, MonadTrans t5, Monad (t5 (t4 (t3 (t2 (t1 m))))), MonadWrap t5 a5 a4, MonadTrans t4, Monad (t4 (t3 (t2 (t1 m)))), MonadWrap t4 a4 a3, MonadTrans t3, Monad (t3 (t2 (t1 m))), MonadWrap t3 a3 a2, MonadTrans t2, Monad (t2 (t1 m)), MonadWrap t2 a2 a1, MonadTrans t1, Monad (t1 m), MonadWrap t1 a1 a0, Monad m) => MultiWrap m (t6 (t5 (t4 (t3 (t2 (t1 m)))))) a6 a0 | |
| (MonadTrans t5, Monad (t5 (t4 (t3 (t2 (t1 m))))), MonadWrap t5 a5 a4, MonadTrans t4, Monad (t4 (t3 (t2 (t1 m)))), MonadWrap t4 a4 a3, MonadTrans t3, Monad (t3 (t2 (t1 m))), MonadWrap t3 a3 a2, MonadTrans t2, Monad (t2 (t1 m)), MonadWrap t2 a2 a1, MonadTrans t1, Monad (t1 m), MonadWrap t1 a1 a0, Monad m) => MultiWrap m (t5 (t4 (t3 (t2 (t1 m))))) a5 a0 | |
| (MonadTrans t4, Monad (t4 (t3 (t2 (t1 m)))), MonadWrap t4 a4 a3, MonadTrans t3, Monad (t3 (t2 (t1 m))), MonadWrap t3 a3 a2, MonadTrans t2, Monad (t2 (t1 m)), MonadWrap t2 a2 a1, MonadTrans t1, Monad (t1 m), MonadWrap t1 a1 a0, Monad m) => MultiWrap m (t4 (t3 (t2 (t1 m)))) a4 a0 | |
| (MonadTrans t3, Monad (t3 (t2 (t1 m))), MonadWrap t3 a3 a2, MonadTrans t2, Monad (t2 (t1 m)), MonadWrap t2 a2 a1, MonadTrans t1, Monad (t1 m), MonadWrap t1 a1 a0, Monad m) => MultiWrap m (t3 (t2 (t1 m))) a3 a0 | |
| (MonadTrans t2, Monad (t2 (t1 m)), MonadWrap t2 a2 a1, MonadTrans t1, Monad (t1 m), MonadWrap t1 a1 a0, Monad m) => MultiWrap m (t2 (t1 m)) a2 a0 | |
| (MonadTrans t1, Monad (t1 m), MonadWrap t1 a1 a0, Monad m) => MultiWrap m (t1 m) a1 a0 |
Example
module Main where
import Control.Monad.MultiLift
import Control.Monad.MultiWrap
import Control.Monad.Reader
import Control.Monad.State
import Control.Monad.Trans
import Control.Monad.Wrap
newtype Type1 = Type1 { unType1 :: String }
type Reader1 = ReaderT Type1 IO
newtype Type2 = Type2 { unType2 :: String }
type Reader2 = ReaderT Type2 Reader1
type Outer = StateT () Reader2
r3 :: Outer ()
r3 = do
-- Note that you have to specify the inner type
s1 <- mlift (asks unType1 :: Reader1 String)
liftIO $ putStrLn $ "s1: " ++ s1
s2 <- mlift (asks unType2 :: Reader2 String)
liftIO $ putStrLn $ "s2: " ++ s2
r2 :: Outer ()
r2 = do
mwrap (local augment :: Reader1 a -> Reader1 a) r3
where
augment (Type1 s) = Type1 $ s ++ " (augmented)"
r1 :: Reader2 ()
r1 = do
liftM fst $ runStateT r3 ()
liftM fst $ runStateT r2 ()
-- runContWrapT r2 return
main :: IO ()
main = do
runReaderT (runReaderT r1 $ Type2 "this is the Reader2 contents")
$ Type1 "this is the Reader1 contents"