packages feed

monadLib 3.1.0 → 3.3.0

raw patch · 4 files changed

+231/−128 lines, 4 files

Files

+ CHANGES view
@@ -0,0 +1,8 @@+Version 3.3.0++* Remove 'RunStateM'+  Simplifies the library without loosing functionality.+  It seems that we can get the same behavior by just using 'get' and 'set'.++* Add functions that use a monad morphism to "derive" implementations+  of most of the funcitons in the library.
monadLib.cabal view
@@ -1,20 +1,18 @@ Name:           monadLib-Version:        3.1.0+Version:        3.3.0 License:        BSD3 License-file:   LICENSE Author:         Iavor S. Diatchki-Maintainer:     diatchki@csee.ogi.edu-Homepage:       http://www.csee.ogi.edu/~diatchki/monadLib+Maintainer:     diatchki@galois.com+Homepage:       http://www.galois.com/~diatchki/monadLib Category:       Monads Synopsis:       A collection of monad transformers. Description:    A collection of monad transformers. hs-source-dirs: src Build-Depends:  base-Extra-source-files: LICENSE README-Exposed-modules: -                 MonadLib-                 Monads-Extensions:     -  MultiParamTypeClasses, FunctionalDependencies+Extra-source-files: LICENSE, README, CHANGES+Exposed-modules: MonadLib, Monads+Extensions:+  MultiParamTypeClasses, FunctionalDependencies, Rank2Types GHC-options:    -O2 -W -fallow-undecidable-instances 
src/MonadLib.hs view
@@ -5,9 +5,9 @@ module MonadLib (   -- * Types   -- $Types-  Id, Lift, ReaderT, WriterT, StateT, ExceptionT, ContT,+  Id, Lift, IdT, ReaderT, WriterT, StateT, ExceptionT, ContT, -  -- * Lifting +  -- * Lifting   -- $Lifting   MonadT(..), BaseM(..), @@ -17,15 +17,22 @@   Label, labelCC, jump,    -- * Execution- +   -- ** Eliminating Effects   -- $Execution-  runId, runLift, runReaderT, runWriterT, runStateT, runExceptionT, runContT, +  runId, runLift,+  runIdT, runReaderT, runWriterT, runStateT, runExceptionT, runContT,    -- ** Nested Execution   -- $Nested_Exec-  RunReaderM(..), RunWriterM(..), RunStateM(..), RunExceptionM(..),+  RunReaderM(..), RunWriterM(..), RunExceptionM(..), +  -- * Deriving functions+  Iso(..), derive_fmap, derive_return, derive_bind, derive_fail, derive_mfix,+  derive_ask, derive_put, derive_get, derive_set, derive_raise, derive_callCC,+  derive_local, derive_collect, derive_try,+  derive_lift, derive_inBase,+   -- * Miscellaneous   version,   module Control.Monad@@ -34,49 +41,53 @@ import Control.Monad import Control.Monad.Fix import Data.Monoid+import Prelude hiding (Ordering(..))  -- | The current version of the library. version :: (Int,Int,Int)-version = (3,1,0)+version = (3,3,0)   -- $Types--- +-- -- The following types define the representations of the -- computation types supported by the library. -- Each type adds support for a different effect.  -- | Computations with no effects.-newtype Id a              = I a                         +newtype Id a              = I a --- | Computation with no effects (stritc).+-- | Computation with no effects (strict). data Lift a               = L a +-- | Add nothing.  Useful as a placeholder.+newtype IdT m a           = IT (m a)+ -- | Add support for propagating a context.-newtype ReaderT    i m a  = R (i -> m a)                +newtype ReaderT    i m a  = R (i -> m a)  -- | Add support for collecting values.-newtype WriterT    i m a  = W (m (a,i))            +newtype WriterT    i m a  = W (m (a,i))  -- | Add support for threading state.-newtype StateT     i m a  = S (i -> m (a,i))           +newtype StateT     i m a  = S (i -> m (a,i))  -- | Add support for exceptions.-newtype ExceptionT i m a  = X (m (Either i a))          +newtype ExceptionT i m a  = X (m (Either i a))  -- | Add support for jumps.-newtype ContT      i m a  = C ((a -> m i) -> m i)       +newtype ContT      i m a  = C ((a -> m i) -> m i)    -- $Execution--- +-- -- The following functions eliminate the outermost effect -- of a computation by translating a computation into an--- equivalent computation in the underlying monad.  --- (The exception is 'Id' which is not a monad transformer --- but an ordinary monad, and so, its run operation simply--- eliminates the monad.)+-- equivalent computation in the underlying monad.+-- (The exceptions are 'Id' and 'Lift' which are not transformers+-- but ordinary monas and so, their run operations simply+-- eliminate the monad.)   -- | Get the result of a pure computation.@@ -87,6 +98,11 @@ runLift       :: Lift a -> a runLift (L a) = a ++-- | Remove an identity layer.+runIdT        :: IdT m a -> m a+runIdT (IT a)  = a+ -- | Execute a reader computation in the given context. runReaderT    :: i -> ReaderT i m a -> m a runReaderT i (R m) = m i@@ -102,7 +118,7 @@ runStateT i (S m) = m i  -- | Execute a computation with exceptions.--- Successful results are tagged with 'Right', +-- Successful results are tagged with 'Right', -- exceptional results are tagged with 'Left'. runExceptionT :: ExceptionT i m a -> m (Either i a) runExceptionT (X m) = m@@ -114,11 +130,11 @@   -- $Lifting--- +-- -- The following operations allow us to promote computations -- in the underlying monad to computations that support an extra -- effect.  Computations defined in this way do not make use of--- the new effect but can be combined with other operations that +-- the new effect but can be combined with other operations that -- utilize the effect.  class MonadT t where@@ -128,9 +144,10 @@ -- It is interesting to note that these use something the resembles -- the non-transformer 'return's. +instance MonadT IdT            where lift m = IT m instance MonadT (ReaderT    i) where lift m = R (\_ -> m) instance MonadT (StateT     i) where lift m = S (\s -> liftM (\a -> (a,s)) m)-instance (Monoid i) => +instance (Monoid i) =>          MonadT (WriterT    i) where lift m = W (liftM (\a -> (a,mempty)) m) instance MonadT (ExceptionT i) where lift m = X (liftM Right m) instance MonadT (ContT      i) where lift m = C (m >>=)@@ -139,16 +156,18 @@ class (Monad m, Monad n) => BaseM m n | m -> n where   -- | Promote a computation from the base monad.   inBase :: n a -> m a- + instance BaseM IO IO        where inBase = id instance BaseM Maybe Maybe  where inBase = id instance BaseM [] []        where inBase = id instance BaseM Id Id        where inBase = id instance BaseM Lift Lift    where inBase = id- ++instance (BaseM m n) => BaseM (IdT          m) n where inBase = lift . inBase instance (BaseM m n) => BaseM (ReaderT    i m) n where inBase = lift . inBase instance (BaseM m n) => BaseM (StateT     i m) n where inBase = lift . inBase-instance (BaseM m n,Monoid i) => BaseM (WriterT    i m) n where inBase = lift . inBase+instance (BaseM m n,Monoid i) =>+                        BaseM (WriterT    i m) n where inBase = lift . inBase instance (BaseM m n) => BaseM (ExceptionT i m) n where inBase = lift . inBase instance (BaseM m n) => BaseM (ContT      i m) n where inBase = lift . inBase @@ -164,35 +183,38 @@   fail x    = error x   L x >>= k = k x --- For the monad transformers, the definition of 'return' +-- For the monad transformers, the definition of 'return' -- is completely determined by the 'lift' operations.  -- None of the transformers make essential use of the 'fail' method. -- Instead they delegate its behavior to the underlying monad. +instance (Monad m) => Monad (IdT m) where+  return x    = lift (return x)+  fail x      = lift (fail x)+  m >>= k     = IT (runIdT m >>= (runIdT . k))+ instance (Monad m) => Monad (ReaderT i m) where   return x = lift (return x)   fail x   = lift (fail x)-  m >>= k  = R $ \r -> runReaderT r m >>= \a -> -                       runReaderT r (k a)+  m >>= k  = R (\r -> runReaderT r m >>= \a -> runReaderT r (k a))  instance (Monad m) => Monad (StateT i m) where   return x = lift (return x)   fail x   = lift (fail x)-  m >>= k  = S $ \s -> runStateT s  m >>= \ ~(a,s') -> -                       runStateT s' (k a)+  m >>= k  = S (\s -> runStateT s m >>= \ ~(a,s') -> runStateT s' (k a))  instance (Monad m,Monoid i) => Monad (WriterT i m) where   return x = lift (return x)   fail x   = lift (fail x)-  m >>= k  = W $ runWriterT m     >>= \ ~(a,w1) -> -                 runWriterT (k a) >>= \ ~(b,w2) -> +  m >>= k  = W $ runWriterT m     >>= \ ~(a,w1) ->+                 runWriterT (k a) >>= \ ~(b,w2) ->                  return (b,mappend w1 w2)  instance (Monad m) => Monad (ExceptionT i m) where   return x = lift (return x)   fail x   = lift (fail x)-  m >>= k  = X $ runExceptionT m >>= \a -> +  m >>= k  = X $ runExceptionT m >>= \a ->                  case a of                    Left x  -> return (Left x)                    Right a -> runExceptionT (k a)@@ -204,6 +226,7 @@  instance                       Functor Id               where fmap = liftM instance                       Functor Lift             where fmap = liftM+instance (Monad m)          => Functor (IdT          m) where fmap = liftM instance (Monad m)          => Functor (ReaderT    i m) where fmap = liftM instance (Monad m)          => Functor (StateT     i m) where fmap = liftM instance (Monad m,Monoid i) => Functor (WriterT    i m) where fmap = liftM@@ -212,11 +235,11 @@   -- $Monadic_Value_Recursion--- +-- -- Recursion that does not duplicate side-effects. -- For details see Levent Erkok's dissertation.--- --- Monadic types built with 'ContT' do not support +--+-- Monadic types built with 'ContT' do not support -- monadic value recursion.  instance MonadFix Id where@@ -225,6 +248,9 @@ instance MonadFix Lift where   mfix f  = let m = f (runLift m) in m +instance (MonadFix m) => MonadFix (IdT m) where+  mfix f  = IT (mfix (runIdT . f))+ instance (MonadFix m) => MonadFix (ReaderT i m) where   mfix f  = R $ \r -> mfix (runReaderT r . f) @@ -241,14 +267,18 @@   +instance (MonadPlus m) => MonadPlus (IdT m) where+  mzero               = lift mzero+  mplus (IT m) (IT n) = IT (mplus m n)+ instance (MonadPlus m) => MonadPlus (ReaderT i m) where   mzero             = lift mzero   mplus (R m) (R n) = R (\r -> mplus (m r) (n r))- + instance (MonadPlus m) => MonadPlus (StateT i m) where   mzero             = lift mzero   mplus (S m) (S n) = S (\s -> mplus (m s) (n s))- + instance (MonadPlus m,Monoid i) => MonadPlus (WriterT i m) where   mzero             = lift mzero   mplus (W m) (W n) = W (mplus m n)@@ -259,7 +289,7 @@   -- $Effects--- +-- -- The following classes define overloaded operations -- that can be used to define effectful computations. @@ -272,7 +302,8 @@ instance (Monad m) => ReaderM (ReaderT i m) i where   ask = R return -instance (ReaderM m j,Monoid i) +instance (ReaderM m j) => ReaderM (IdT          m) j where ask = lift ask+instance (ReaderM m j,Monoid i)                        => ReaderM (WriterT    i m) j where ask = lift ask instance (ReaderM m j) => ReaderM (StateT     i m) j where ask = lift ask instance (ReaderM m j) => ReaderM (ExceptionT i m) j where ask = lift ask@@ -284,9 +315,10 @@   -- | Add a value to the collection.   put  :: i -> m () -instance (Monad m,Monoid i) => WriterM (WriterT i m) i where +instance (Monad m,Monoid i) => WriterM (WriterT i m) i where   put x = W (return ((),x)) +instance (WriterM m j) => WriterM (IdT          m) j where put = lift . put instance (WriterM m j) => WriterM (ReaderT    i m) j where put = lift . put instance (WriterM m j) => WriterM (StateT     i m) j where put = lift . put instance (WriterM m j) => WriterM (ExceptionT i m) j where put = lift . put@@ -295,7 +327,7 @@  -- | Classifies monads that propagate a state component of type @i@. class (Monad m) => StateM m i | m -> i where-  -- | Get the state. +  -- | Get the state.   get :: m i   -- | Set the state.   set :: i -> m ()@@ -304,9 +336,12 @@   get   = S (\s -> return (s,s))   set s = S (\_ -> return ((),s)) +instance (StateM m j) => StateM (IdT m) j where+  get = lift get+  set = lift . set instance (StateM m j) => StateM (ReaderT i m) j where   get = lift get-  set = lift . set +  set = lift . set instance (StateM m j,Monoid i) => StateM (WriterT i m) j where   get = lift get   set = lift . set@@ -320,12 +355,14 @@  -- | Classifies monads that support raising exceptions of type @i@. class (Monad m) => ExceptionM m i | m -> i where-  -- | Raise an exception.  +  -- | Raise an exception.   raise :: i -> m a -instance (Monad m) => ExceptionM (ExceptionT i m) i where -  raise x = X (return (Left x)) +instance (Monad m) => ExceptionM (ExceptionT i m) i where+  raise x = X (return (Left x)) +instance (ExceptionM m j) => ExceptionM (IdT m) j where+  raise = lift . raise instance (ExceptionM m j) => ExceptionM (ReaderT i m) j where   raise = lift . raise instance (ExceptionM m j,Monoid i) => ExceptionM (WriterT i m) j where@@ -344,6 +381,9 @@   -- | Capture the current continuation.   callCC :: ((a -> m b) -> m a) -> m a +instance (ContM m) => ContM (IdT m) where+  callCC f = IT $ callCC $ \k -> runIdT $ f $ \a -> lift $ k a+ instance (ContM m) => ContM (ReaderT i m) where   callCC f = R $ \r -> callCC $ \k -> runReaderT r $ f $ \a -> lift $ k a @@ -352,10 +392,10 @@  instance (ContM m,Monoid i) => ContM (WriterT i m) where   callCC f = W $ callCC $ \k -> runWriterT $ f $ \a -> lift $ k (a,mempty)- + instance (ContM m) => ContM (ExceptionT i m) where   callCC f = X $ callCC $ \k -> runExceptionT $ f $ \a -> lift $ k $ Right a-   + instance (Monad m) => ContM (ContT i m) where   callCC f = C $ \k -> runContT k $ f $ \a -> C $ \_ -> k a @@ -364,11 +404,9 @@ -- -- The following classes define operations that are overloaded -- versions of the @run@ operations.   Unlike the @run@ operations,--- functions do not change the type of the computation (i.e, they--- do not remove a layer).  However, they do not perform any--- side-effects in the corresponding layer.  Instead, they execute--- a computation in a ``separate thread'' with respect to the--- corresponding effect.  +-- these functions do not change the type of the computation (i.e, they+-- do not remove a layer).  Instead, they perform the effects in+-- a ``separate effect thread''.  -- | Classifies monads that support changing the context for a -- sub-computation.@@ -378,6 +416,9 @@  instance (Monad m)        => RunReaderM (ReaderT    i m) i where   local i m     = lift (runReaderT i m)++instance (RunReaderM m j) => RunReaderM (IdT m) j where+  local i (IT m) = IT (local i m) instance (RunReaderM m j,Monoid i) => RunReaderM (WriterT i m) j where   local i (W m) = W (local i m) instance (RunReaderM m j) => RunReaderM (StateT     i m) j where@@ -385,12 +426,15 @@ instance (RunReaderM m j) => RunReaderM (ExceptionT i m) j where   local i (X m) = X (local i m) --- | Classifies monads that support collecting the output of +-- | Classifies monads that support collecting the output of -- a sub-computation. class WriterM m i => RunWriterM m i | m -> i where-  -- | Collect the output from a computation.   +  -- | Collect the output from a computation.   collect :: m a -> m (a,i) +instance (RunWriterM m j) => RunWriterM (IdT m) j where+  collect (IT m) = IT (collect m)+ instance (RunWriterM m j) => RunWriterM (ReaderT i m) j where   collect (R m) = R (collect . m) @@ -404,50 +448,30 @@ instance (RunWriterM m j) => RunWriterM (ExceptionT i m) j where   collect (X m) = X (liftM swap (collect m))     where swap (Right a,w)  = Right (a,w)-          swap (Left x,_)   = Left x    +          swap (Left x,_)   = Left x     -- NOTE: If the local computation fails, then the output     -- is discarded because the result type cannot accommodate it.  --- | Classifies monads that support separate state threads.-class (StateM m i) => RunStateM m i | m -> i where-  -- | Modify the state for the duration of a computation.-  -- Returns the final state.-  runS :: i -> m a -> m (a,i)   --instance (RunStateM m j) => RunStateM (ReaderT i m) j where-  runS s (R m)  = R (runS s . m)--instance (RunStateM m j,Monoid i) => RunStateM (WriterT i m) j where-  runS s (W m)  = W (liftM swap (runS s m))-    where swap (~(a,s),w) = ((a,w),s)--instance (Monad m) => RunStateM (StateT i m) i where-  runS s m  = lift (runStateT s m)--instance (RunStateM m j) => RunStateM (ExceptionT i m) j where-  runS s (X m)  = X (liftM swap (runS s m))-    where swap (Left e,_)   = Left e    -          swap (Right a,s)  = Right (a,s)-    -- NOTE: If the local computation fails, then the modifications-    -- are discarded because the result type cannot accommodate it.- -- | Classifies monads that support handling of exceptions. class ExceptionM m i => RunExceptionM m i | m -> i where   -- | Exceptions are explicit in the result.-  try :: m a -> m (Either i a)  +  try :: m a -> m (Either i a) +instance (RunExceptionM m i) => RunExceptionM (IdT m) i where+  try (IT m) = IT (try m)+ instance (RunExceptionM m i) => RunExceptionM (ReaderT j m) i where   try (R m) = R (try . m)  instance (RunExceptionM m i,Monoid j) => RunExceptionM (WriterT j m) i where   try (W m) = W (liftM swap (try m))-    where swap (Right ~(a,w)) = (Right a,w)  +    where swap (Right ~(a,w)) = (Right a,w)           swap (Left e)       = (Left e, mempty)  instance (RunExceptionM m i) => RunExceptionM (StateT j m) i where   try (S m) = S (\s -> liftM (swap s) (try (m s)))-    where swap _ (Right ~(a,s)) = (Right a,s)  +    where swap _ (Right ~(a,s)) = (Right a,s)           swap s (Left e)       = (Left e, s)  instance (Monad m) => RunExceptionM (ExceptionT i m) i where@@ -459,7 +483,7 @@ -- | An explicit representation for continuations that store a value. newtype Label m a    = Lab ((a, Label m a) -> m ()) --- | Capture the current continuation.  +-- | Capture the current continuation -- This function is like 'return', except that it also captures -- the current continuation.  Later we can use 'jump' to go back to -- the continuation with a possibly different value.@@ -472,5 +496,69 @@   where unreachable = error "(bug) jump: unreachable"  +-- | A isomorphism between (usually) monads.+-- Typically the constructor and selector of a newtype delcaration.+data Iso m n = Iso { close :: forall a. m a -> n a,+                     open  :: forall a. n a -> m a } +-- | Derive the implementation of 'fmap' from 'Functor'.+derive_fmap :: (Functor m) => Iso m n -> (a -> b) -> n a -> n b+derive_fmap iso f m = close iso (fmap f (open iso m))++-- | Derive the implementation of 'return' from 'Monad'.+derive_return :: (Monad m) => Iso m n -> (a -> n a)+derive_return iso a = close iso (return a)++-- | Derive the implementation of '>>=' from 'Monad'.+derive_bind :: (Monad m) => Iso m n -> n a -> (a -> n b) -> n b+derive_bind iso m k = close iso ((open iso m) >>= \x -> open iso (k x))++derive_fail :: (Monad m) => Iso m n -> String -> n a+derive_fail iso a = close iso (fail a)++-- | Derive the implementation of 'mfix' from 'MonadFix'.+derive_mfix :: (MonadFix m) => Iso m n -> (a -> n a) -> n a+derive_mfix iso f = close iso (mfix (open iso . f))++-- | Derive the implementation of 'ask' from 'ReaderM'.+derive_ask :: (ReaderM m i) => Iso m n -> n i+derive_ask iso = close iso ask++-- | Derive the implementation of 'put' from 'WriterM'.+derive_put :: (WriterM m i) => Iso m n -> i -> n ()+derive_put iso x = close iso (put x)++-- | Derive the implementation of 'get' from 'StateM'.+derive_get :: (StateM m i) => Iso m n -> n i+derive_get iso = close iso get++-- | Derive the implementation of 'set' from 'StateM'.+derive_set :: (StateM m i) => Iso m n -> i -> n ()+derive_set iso x = close iso (set x)++-- | Derive the implementation of 'raise' from 'ExceptionM'.+derive_raise :: (ExceptionM m i) => Iso m n -> i -> n a+derive_raise iso x = close iso (raise x)++-- | Derive the implementation of 'callCC' from 'ContM'.+derive_callCC :: (ContM m) => Iso m n -> ((a -> n b) -> n a) -> n a+derive_callCC iso f = close iso (callCC (open iso . f . (close iso .)))++-- | Derive the implementation of 'local' from 'RunReaderM'.+derive_local :: (RunReaderM m i) => Iso m n -> i -> n a -> n a+derive_local iso i = close iso . local i . open iso++-- | Derive the implementation of 'collect' from 'RunWriterM'.+derive_collect :: (RunWriterM m i) => Iso m n -> n a -> n (a,i)+derive_collect iso = close iso . collect . open iso++-- | Derive the implementation of 'try' from 'RunExceptionM'.+derive_try :: (RunExceptionM m i) => Iso m n -> n a -> n (Either i a)+derive_try iso = close iso . try . open iso++derive_lift :: (MonadT t, Monad m) => Iso (t m) n -> m a -> n a+derive_lift iso m = close iso (lift m)++derive_inBase :: (BaseM m x) => Iso m n -> x a -> n a+derive_inBase iso m = close iso (inBase m) 
src/Monads.hs view
@@ -22,6 +22,12 @@ newtype Exception i a     = X' { unX :: ExceptionT  i Id a } newtype Cont      i a     = C' { unC :: ContT       i Id a } +iso_R = Iso R' unR+iso_W = Iso W' unW+iso_S = Iso S' unS+iso_X = Iso X' unX+iso_C = Iso C' unC+ instance               BaseM (Reader    i) (Reader    i) where inBase = id instance (Monoid i) => BaseM (Writer    i) (Writer    i) where inBase = id instance               BaseM (State     i) (State     i) where inBase = id@@ -29,46 +35,46 @@ instance               BaseM (Cont      i) (Cont      i) where inBase = id  instance Monad (Reader i) where-  return x    = R' (return x)-  fail x      = R' (fail x)-  m >>= f     = R' (unR m >>= (unR . f))+  return  = derive_return iso_R+  fail    = derive_fail iso_R+  (>>=)   = derive_bind iso_R  instance (Monoid i) => Monad (Writer i) where-  return x    = W' (return x)-  fail x      = W' (fail x)-  m >>= f     = W' (unW m >>= (unW . f))+  return  = derive_return iso_W+  fail    = derive_fail iso_W+  (>>=)   = derive_bind iso_W  instance Monad (State i) where-  return x    = S' (return x)-  fail x      = S' (fail x)-  m >>= f     = S' (unS m >>= (unS . f))+  return  = derive_return iso_S+  fail    = derive_fail iso_S+  (>>=)   = derive_bind iso_S  instance Monad (Exception i) where-  return x    = X' (return x)-  fail x      = X' (fail x)-  m >>= f     = X' (unX m >>= (unX . f))+  return  = derive_return iso_X+  fail    = derive_fail iso_X+  (>>=)   = derive_bind iso_X  instance Monad (Cont i) where-  return x    = C' (return x)-  fail x      = C' (fail x)-  m >>= f     = C' (unC m >>= (unC . f))+  return  = derive_return iso_C+  fail    = derive_fail iso_C+  (>>=)   = derive_bind iso_C -instance               Functor (Reader    i) where fmap = liftM-instance (Monoid i) => Functor (Writer    i) where fmap = liftM-instance               Functor (State     i) where fmap = liftM-instance               Functor (Exception i) where fmap = liftM-instance               Functor (Cont      i) where fmap = liftM+instance               Functor (Reader    i) where fmap = derive_fmap iso_R+instance (Monoid i) => Functor (Writer    i) where fmap = derive_fmap iso_W+instance               Functor (State     i) where fmap = derive_fmap iso_S+instance               Functor (Exception i) where fmap = derive_fmap iso_X+instance               Functor (Cont      i) where fmap = derive_fmap iso_C -instance               MonadFix (Reader    i) where mfix f = R' (mfix (unR . f))-instance (Monoid i) => MonadFix (Writer    i) where mfix f = W' (mfix (unW . f))-instance               MonadFix (State     i) where mfix f = S' (mfix (unS . f))-instance               MonadFix (Exception i) where mfix f = X' (mfix (unX . f))+instance               MonadFix (Reader    i) where mfix = derive_mfix iso_R+instance (Monoid i) => MonadFix (Writer    i) where mfix = derive_mfix iso_W+instance               MonadFix (State     i) where mfix = derive_mfix iso_S+instance               MonadFix (Exception i) where mfix = derive_mfix iso_X -instance ReaderM (Reader i) i where ask = R' ask-instance (Monoid i) => WriterM (Writer i) i where put = W' . put -instance StateM (State i) i where get = S' get; set = S' . set -instance ExceptionM (Exception i) i where raise = X' . raise -instance ContM (Cont i) where callCC f = C' (callCC (unC . f . (C' .)))+instance ReaderM (Reader i) i where ask = derive_ask iso_R+instance (Monoid i) => WriterM (Writer i) i where put = derive_put iso_W+instance StateM (State i) i where get = derive_get iso_S; set = derive_set iso_S+instance ExceptionM (Exception i) i where raise = derive_raise iso_X+instance ContM (Cont i) where callCC = derive_callCC iso_C  runReader     :: i -> Reader i a -> a runWriter     :: Writer i a -> (a,i)@@ -76,17 +82,20 @@ runException  :: Exception i a -> Either i a runCont       :: (a -> i) -> Cont i a -> i -runReader i  = runId . runReaderT i          . unR +runReader i  = runId . runReaderT i          . unR runWriter    = runId . runWriterT            . unW runState  i  = runId . runStateT i           . unS runException = runId . runExceptionT         . unX-runCont   i  = runId . runContT (return . i) . unC +runCont   i  = runId . runContT (return . i) . unC -instance RunReaderM (Reader i) i where local i = R' . local i . unR-instance RunStateM (State i) i where runS i  = S' . runS i  . unS+instance RunReaderM (Reader i) i where+  local = derive_local iso_R+ instance (Monoid i) => RunWriterM (Writer i) i where-  collect = W' . collect . unW-instance RunExceptionM (Exception i) i where try = X' . try     . unX+  collect = derive_collect iso_W++instance RunExceptionM (Exception i) i where+  try = derive_try iso_X