packages feed

effects 0.1 → 0.2

raw patch · 9 files changed

+229/−87 lines, 9 filesdep +newtypedep −transformersPVP ok

version bump matches the API change (PVP)

Dependencies added: newtype

Dependencies removed: transformers

API changes (from Hackage documentation)

- Control.Effects: data ContT r m :: (* -> *) a :: * -> (* -> *) -> * -> *
- Control.Effects: data Proxy m :: (* -> *)
- Control.Effects: instance (AutoLift' m1 m2 IO n, Monad m2) => AutoLift' m1 (ContT r m2) IO (ContT s n)
- Control.Effects: instance (AutoLift' m1 m2 Identity n, Monad m2) => AutoLift' m1 (ContT r m2) Identity (ContT s n)
- Control.Effects: instance AutoLift' m1 m2 m1 m2 => AutoLift m1 m2
- Control.Effects: instance AutoLift' m1 m2 n1 n2 => AutoLift' m1 m2 (ContT r1 n1) (ContT r2 n2)
- Control.Effects: instance m1 ~ m2 => AutoLift' m1 m2 IO IO
- Control.Effects: instance m1 ~ m2 => AutoLift' m1 m2 Identity Identity
- Control.Effects: io :: AutoLift IO n => IO a -> n a
- Control.Effects: runIO :: IO () -> IO ()
- Control.Effects.Set: choose :: (c ~ (ContT (Set r) m), AutoLift c n, Monad m, Ord r) => Proxy c -> [a] -> n a
- Control.Effects.Set: set :: (Monad m, Ord a) => Handler (Set a) (Set a) m a
+ Control.Effects: base :: AutoLiftBase m n => m a -> n a
+ Control.Effects: class (Monad m, Monad n) => AutoLiftBase m n
+ Control.Effects: data Base m a
+ Control.Effects: data Effect e m :: (* -> *)
+ Control.Effects: data Layer e m a
+ Control.Effects: data Pure a
+ Control.Effects: instance (Monad m, Monad n, AutoLiftInternal (Base m) (Base n) (Base m) (Base n)) => AutoLiftBase m (Base n)
+ Control.Effects: instance (Monad m, Monad n, AutoLiftInternal (Base m) (Layer e n) (Base m) (Layer e n)) => AutoLiftBase m (Layer e n)
+ Control.Effects: instance (Monad m, Monad n, AutoLiftInternal (Layer e m) (Base n) (Layer e m) (Base n)) => AutoLift e m (Base n)
+ Control.Effects: instance (Monad m, Monad n, AutoLiftInternal (Layer e m) (Layer d n) (Layer e m) (Layer d n)) => AutoLift e m (Layer d n)
+ Control.Effects: instance Applicative (Layer r m)
+ Control.Effects: instance Applicative Pure
+ Control.Effects: instance Applicative m => Applicative (Base m)
+ Control.Effects: instance AutoLiftInternal m1 m2 (Base n1) n2 => AutoLiftInternal m1 (Layer r m2) (Base n1) (Layer s n2)
+ Control.Effects: instance AutoLiftInternal m1 m2 n1 n2 => AutoLiftInternal m1 m2 (Layer r n1) (Layer s n2)
+ Control.Effects: instance Functor (Layer r m)
+ Control.Effects: instance Functor Pure
+ Control.Effects: instance Functor m => Functor (Base m)
+ Control.Effects: instance Monad (Layer e m)
+ Control.Effects: instance Monad Pure
+ Control.Effects: instance Monad m => AutoLiftInternal m m (Base n) (Base n)
+ Control.Effects: instance Monad m => Monad (Base m)
+ Control.Effects: runBase :: Base m a -> m a
+ Control.Effects.NonDet: accumulate :: (Monad m, Newtype n o) => (a -> n) -> Handler n o m a
+ Control.Effects.NonDet: alternatives :: (Monad m, Alternative f) => Handler (WrappedAlt f a) (f a) m a
+ Control.Effects.NonDet: bfs :: (Monad m, Monoid r) => (a -> r) -> Handler (BFS r) r m a
+ Control.Effects.NonDet: choose :: (AutoLift r m n, Monoid r, Foldable f) => Effect r m -> f a -> n a
+ Control.Effects.NonDet: dfs :: (Monad m, Monoid r) => (a -> r) -> Handler r r m a
+ Control.Effects.NonDet: instance (Monad m, Monoid r) => Monoid (WrappedMonad m r)
+ Control.Effects.NonDet: instance Alternative f => Monoid (WrappedAlt f a)
+ Control.Effects.NonDet: instance Monoid r => Monoid (BFS r)
+ Control.Effects.NonDet: instance Monoid r => Newtype (BFS r) r
+ Control.Effects.NonDet: instance Newtype (WrappedAlt m a) (m a)
+ Control.Effects.NonDet: set :: (Monad m, Ord a) => Handler (Set a) (Set a) m a
+ Control.Effects.State: (=:) :: AutoLift (State s m a) m n => Effect (State s m a) m -> n s -> n ()
+ Control.Effects.State: local :: AutoLift (State s m a) m n => Effect (State s m a) m -> (s -> s) -> n b -> n b
+ Control.Effects.State: modify :: AutoLift (State s m a) m n => Effect (State s m a) m -> (s -> s) -> n ()
+ Control.Effects.State: type State s m a = s -> m a
- Control.Effects: class AutoLift m1 m2
+ Control.Effects: class (Monad m, Monad n) => AutoLift e m n
- Control.Effects: operation :: (c ~ (ContT e m), AutoLift c n) => Proxy c -> ((a -> m e) -> m e) -> n a
+ Control.Effects: operation :: AutoLift e m n => Effect e m -> ((a -> m e) -> m e) -> n a
- Control.Effects: run :: Identity a -> a
+ Control.Effects: run :: Base Pure a -> a
- Control.Effects: with :: Monad m => Handler e r m a -> (Proxy (ContT e m) -> ContT e m a) -> m r
+ Control.Effects: with :: Monad m => Handler e r m a -> (Effect e m -> Layer e m a) -> m r
- Control.Effects.Cont: shift :: (c ~ (ContT r m), AutoLift c n, Monad m) => Proxy c -> ((m a -> m r) -> m r) -> n a
+ Control.Effects.Cont: shift :: AutoLift r m n => Effect r m -> ((m a -> m r) -> m r) -> n a
- Control.Effects.Either: throwEither :: (c ~ (ContT (Either e r) m), AutoLift c n, Monad m) => Proxy c -> e -> n Void
+ Control.Effects.Either: throwEither :: AutoLift (Either e r) m n => Effect (Either e r) m -> e -> n Void
- Control.Effects.Error: throwError :: (c ~ (ContT ((e -> m r) -> m r) m), AutoLift c n, Monad m) => Proxy c -> e -> n Void
+ Control.Effects.Error: throwError :: AutoLift ((e -> m r) -> m r) m n => Effect ((e -> m r) -> m r) m -> e -> n Void
- Control.Effects.State: get :: (c ~ (ContT (s -> m r) m), AutoLift c n, Monad m) => Proxy c -> n s
+ Control.Effects.State: get :: AutoLift (State s m a) m n => Effect (State s m a) m -> n s
- Control.Effects.State: put :: (c ~ (ContT (s -> m r) m), AutoLift c n, Monad m) => Proxy c -> s -> n ()
+ Control.Effects.State: put :: AutoLift (State s m a) m n => Effect (State s m a) m -> s -> n ()
- Control.Effects.State: ref :: Monad m => s -> Handler (s -> m a) a m a
+ Control.Effects.State: ref :: Monad m => s -> Handler (State s m a) a m a
- Control.Effects.Writer: tell :: (c ~ (ContT (w, r) m), AutoLift c n, Monad m, Monoid w) => Proxy c -> w -> n ()
+ Control.Effects.Writer: tell :: (AutoLift (w, r) m n, Monoid w) => Effect (w, r) m -> w -> n ()

Files

effects.cabal view
@@ -1,8 +1,11 @@ name:                effects-version:             0.1+version:             0.2 synopsis:            Computational Effects -description:         An alternative to Monad Transformers.+description:         Control.Effects is a library for programming with effects, like in the the Eff language by +                     Andrej Bauer and Matija Pretnar. Effects can be used instead of monad transformers.+                     .+                     See the home page for some example code.  category:            Control, Monads license:             BSD3@@ -20,14 +23,14 @@   HS-Source-Dirs:      src   build-depends:       base >= 3 && < 5,                         containers  >= 0.4 && < 0.5,-                       transformers >= 0.2 && < 0.3,+                       newtype >= 0.2 && < 0.3,                        void   exposed-modules:          Control.Effects     Control.Effects.Cont     Control.Effects.Either     Control.Effects.Error-    Control.Effects.Set+    Control.Effects.NonDet     Control.Effects.State     Control.Effects.Writer     
src/Control/Effects.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, ScopedTypeVariables, FlexibleInstances, FlexibleContexts, UndecidableInstances #-}+{-# LANGUAGE MultiParamTypeClasses, KindSignatures, ScopedTypeVariables, FlexibleInstances, FlexibleContexts, UndecidableInstances #-} module Control.Effects (    -- * Running effects@@ -9,19 +9,22 @@   -- $defdoc   , Handler(..)   , operation-  -- * I/O-  , runIO-  , io+  -- * Base monad+  -- $basedoc+  , runBase+  , base   -- * Effects machinery-  , ContT-  , Proxy+  -- $macdoc+  , Layer+  , Base+  , Pure+  , Effect   , AutoLift+  , AutoLiftBase  ) where -import Control.Monad.Trans.Class (lift)-import Control.Monad.Trans.Cont-import Data.Functor.Identity+import Control.Applicative  -- $rundoc -- Here's an example how to use the state effect from 'Control.Effects.State'.@@ -33,28 +36,30 @@ -- >     put u (val + 5) -- >     get u --- | @with@ takes a handler and creates a new @Proxy@ (effect identifier).---   The @Proxy@ is passed on to a function which can use it to do operations with it.-with :: Monad m => Handler e r m a -> (Proxy (ContT e m) -> ContT e m a) -> m r-with h f = runContT (f Proxy) (ret h) >>= fin h+-- | @with@ takes a handler and creates a new effect instance.+--   The @Effect@ is passed on to a function which can use it to do operations with it.+with :: Monad m => Handler e r m a -> (Effect e m -> Layer e m a) -> m r+with h f = runLayer (f Effect) (ret h) >>= fin h  -- | Unwrap the result of the top-level effect.-run :: Identity a -> a-run = runIdentity+run :: Base Pure a -> a+run (Base (Pure a)) = a   -- $defdoc--- Here's and example how to define the state effect from 'Control.Effects.State'.+-- Here's and example how to define the state effect from 'Control.Effects.Writer'. ----- > ref :: Monad m => s -> Handler (s -> m a) a m a--- > ref s_init = Handler--- >   { ret = return . return . return--- >   , fin = \f -> f s_init+-- > writer :: (Monad m, Monoid w) => Handler (w, a) (w, a) m a+-- > writer = Handler+-- >   { ret = \a -> return (mempty, a)+-- >   , fin = return -- >   }--- >--- > get p   = operation p $ \k -> return $ \s -> do r <- k s; r s--- > put p s = operation p $ \k -> return $ \_ -> do r <- k (); r s- +-- > +-- > tell :: (AutoLift (w, r) m n, Monoid w) => Effect (w, r) m -> w -> n ()+-- > tell p v = operation p $ \k -> do+-- >   (w, r) <- k ()+-- >   return (mappend v w, r)+ -- | A @Handler e r m a@ is a handler of effects with type @e@.  --   The @ret@ field provides a function to lift pure values into the effect. --   The @fin@ field provides a function to extract a final value of type @r@ from the effect.@@ -64,41 +69,116 @@   , fin :: e -> m r   } --- | Define an operation, which is autolifted so it can be used inside other effects.-operation :: forall c m n a e. (c ~ ContT e m, AutoLift c n) => Proxy c -> ((a -> m e) -> m e) -> n a-operation p f = autolift p (Proxy :: Proxy n) (ContT f)+-- | @operation@ takes an effect identifier generated by `with` and a function which takes a continuation as parameter.+--   The result is auto-lifted so it can be used inside any other effect.+operation :: AutoLift e m n => Effect e m -> ((a -> m e) -> m e) -> n a+operation = operation'  --- | Variant of 'run' that allows I/O effects. (Just the identity function, but it helps the type checker.)-runIO :: IO () -> IO ()-runIO = id+-- $basedoc+-- The effects are layered on top of a base monad. Here's an example how to use `IO` as a base monad.+-- +-- > exampleIO :: IO ()+-- > exampleIO = runBase $ do+-- >   with (ref 5) $ \x -> do+-- >     val <- get x+-- >     base $ print val --- | Convert an 'IO' action to an I/O effect operation.-io :: AutoLift IO n => IO a -> n a-io m = autolift (Proxy :: Proxy IO) (Proxy :: Proxy n) m+-- | @base@ takes a computation in the base monad and auto-lifts it so it can be used inside any effect.+base :: AutoLiftBase m n => m a -> n a+base = base' +-- | Unwrap the result of a computation using a base monad.+runBase :: Base m a -> m a+runBase (Base m) = m -data Proxy (m :: * -> *) = Proxy -class AutoLift' m1 m2 n1 n2 where-  autolift' :: Proxy n1 -> Proxy n2 -> m1 a -> m2 a+-- $macdoc+-- Effects are layered in a stack on top of a base monad. Just like with monad transformers, operations lower in the stack+-- need to be lifted to be able to be used together with operations higher in the stack. But as there are only two  monads+-- in play, `Layer` and `Base`, and because each operation is identified with exactly one layer using the `Effect` type,+-- lifting can be done automatically.+--+-- The following types and classes show up in the type signatures. The compiler should be able to infer them for you. -instance (m1 ~ m2) => AutoLift' m1 m2 IO IO where-  autolift' Proxy Proxy = id-instance (m1 ~ m2) => AutoLift' m1 m2 Identity Identity where-  autolift' Proxy Proxy = id+-- | @Layer e m@ is a monad that adds an effect @e@ to the underlying monad @m@.+--   (It is the continuation monad transformer with a friendlier name.)+newtype Layer e m a = Layer { runLayer :: (a -> m e) -> m e } -pre :: Proxy (ContT r m) -> Proxy m-pre Proxy = Proxy-instance (AutoLift' m1 m2 IO n, Monad m2) => AutoLift' m1 (ContT r m2) IO (ContT s n) where-  autolift' p1 p2 = lift . autolift' p1 (pre p2)-instance (AutoLift' m1 m2 Identity n, Monad m2) => AutoLift' m1 (ContT r m2) Identity (ContT s n) where-  autolift' p1 p2 = lift . autolift' p1 (pre p2)+instance Functor (Layer r m) where+  fmap f m = Layer $ \k -> runLayer m (k . f) -instance (AutoLift' m1 m2 n1 n2) => AutoLift' m1 m2 (ContT r1 n1) (ContT r2 n2) where-  autolift' p1 p2 = autolift' (pre p1) (pre p2)+instance Applicative (Layer r m) where+  pure a   = Layer $ \k -> k a+  m <*> v  = Layer $ \k -> runLayer m (\f -> runLayer v (k . f)) -class AutoLift m1 m2 where-  autolift :: Proxy m1 -> Proxy m2 -> m1 a -> m2 a-instance AutoLift' m1 m2 m1 m2 => AutoLift m1 m2 where-  autolift = autolift'+instance Monad (Layer e m) where+  return a = Layer $ \k -> k a+  m >>= f  = Layer $ \k -> runLayer m (\a -> runLayer (f a) k)+++-- | @Pure@ is the identity monad and is used when no other base monad is needed.+newtype Pure a = Pure a++instance Functor Pure where+  fmap f (Pure a) = Pure (f a)++instance Applicative Pure where+  pure = Pure+  Pure f <*> Pure a = Pure (f a)  +  +instance Monad Pure where+  return = Pure+  Pure a >>= f = f a+++-- | @Base m@ is a newtype wrapper around a monadic computation.+newtype Base m a = Base (m a)++instance Functor m => Functor (Base m) where+  fmap f (Base m) = Base (fmap f m)++instance Applicative m => Applicative (Base m) where+  pure = Base . pure+  Base m <*> Base v = Base (m <*> v)+  +instance Monad m => Monad (Base m) where+  return = Base . return+  Base m >>= f = Base $ m >>= runBase . f++-- | @Effect e m@ is a proxy for the type checker to be able to work with multiple effects at the same time.+data Effect e (m :: * -> *) = Effect+++class (Monad m, Monad n) => AutoLift e m n where+  operation' :: Effect e m -> ((a -> m e) -> m e) -> n a++instance (Monad m, Monad n, AutoLiftInternal (Layer e m) (Base    n) (Layer e m) (Base    n)) => AutoLift e m (Base    n) where+  operation' _ f = autolift (Proxy :: Proxy (Layer e m)) (Proxy :: Proxy (Base    n)) (Layer f)+instance (Monad m, Monad n, AutoLiftInternal (Layer e m) (Layer d n) (Layer e m) (Layer d n)) => AutoLift e m (Layer d n) where+  operation' _ f = autolift (Proxy :: Proxy (Layer e m)) (Proxy :: Proxy (Layer d n)) (Layer f)+++class (Monad m, Monad n) => AutoLiftBase m n where+  base' :: m a -> n a++instance (Monad m, Monad n, AutoLiftInternal (Base    m) (Base    n) (Base    m) (Base    n)) => AutoLiftBase m (Base    n) where+  base' m        = autolift (Proxy :: Proxy (Base    m)) (Proxy :: Proxy (Base    n)) (Base m)+instance (Monad m, Monad n, AutoLiftInternal (Base    m) (Layer e n) (Base    m) (Layer e n)) => AutoLiftBase m (Layer e n) where+  base' m        = autolift (Proxy :: Proxy (Base    m)) (Proxy :: Proxy (Layer e n)) (Base m)+++data Proxy (m :: * -> *) = Proxy++class (Monad m1, Monad m2) =>  AutoLiftInternal m1 m2 n1 n2 where+  autolift :: Proxy n1 -> Proxy n2 -> m1 a -> m2 a++pre :: Proxy (Layer r m) -> Proxy m+pre Proxy = Proxy++instance (Monad m)                             => AutoLiftInternal m           m   (Base    n)  (Base    n)  where+  autolift Proxy Proxy = id+instance (AutoLiftInternal m1 m2 (Base n1) n2) => AutoLiftInternal m1 (Layer r m2) (Base    n1) (Layer s n2) where+  autolift p1 p2 = Layer . (>>=) . autolift p1 (pre p2)+instance (AutoLiftInternal m1 m2       n1  n2) => AutoLiftInternal m1          m2  (Layer r n1) (Layer s n2) where+  autolift p1 p2 = autolift (pre p1) (pre p2)
src/Control/Effects/Cont.hs view
@@ -1,9 +1,9 @@-{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-}+{-# LANGUAGE FlexibleContexts #-} module Control.Effects.Cont where  import Control.Effects -shift :: (c ~ ContT r m, AutoLift c n, Monad m) => Proxy c -> ((m a -> m r) -> m r) -> n a+shift :: AutoLift r m n => Effect r m -> ((m a -> m r) -> m r) -> n a shift p c = operation p $ \k -> c (>>= k)  reset :: Monad m => Handler a a m a
src/Control/Effects/Either.hs view
@@ -1,10 +1,10 @@-{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-}+{-# LANGUAGE FlexibleContexts #-} module Control.Effects.Either where  import Control.Effects import Data.Void -throwEither :: (c ~ ContT (Either e r) m, AutoLift c n, Monad m) => Proxy c -> e -> n Void+throwEither :: AutoLift (Either e r) m n => Effect (Either e r) m -> e -> n Void throwEither p e = operation p $ \_ -> return $ Left e  catchEither :: Monad m => (e -> m a) -> Handler (Either e a) a m a
src/Control/Effects/Error.hs view
@@ -1,10 +1,10 @@-{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-}+{-# LANGUAGE FlexibleContexts #-} module Control.Effects.Error where  import Control.Effects import Data.Void -throwError :: (c ~ ContT ((e -> m r) -> m r) m, AutoLift c n, Monad m) => Proxy c -> e -> n Void+throwError :: AutoLift ((e -> m r) -> m r) m n => Effect ((e -> m r) -> m r) m -> e -> n Void throwError p e = operation p $ \_ -> return $ \h -> h e  catchError :: Monad m => (e -> m a) -> Handler ((e -> m a) -> m a) a m a
+ src/Control/Effects/NonDet.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts, FlexibleInstances #-}+module Control.Effects.NonDet (choose, dfs, set, alternatives, accumulate, bfs) where++import Control.Effects+import qualified Data.Set as Set+import Prelude hiding (foldr)+import Data.Foldable+import Data.Monoid+import Control.Applicative+import Control.Monad+import Control.Newtype++instance (Monad m, Monoid r) => Monoid (WrappedMonad m r) where+  mempty                              = WrapMonad $ return mempty+  mappend (WrapMonad a) (WrapMonad b) = WrapMonad $ liftM2 mappend a b++newtype WrappedAlt f a = WrapAlt (f a)+instance Newtype (WrappedAlt m a) (m a) where+  pack = WrapAlt+  unpack (WrapAlt a) = a+instance Alternative f => Monoid (WrappedAlt f a) where+  mempty                          = WrapAlt empty+  mappend (WrapAlt a) (WrapAlt b) = WrapAlt $ a <|> b++choose :: (AutoLift r m n, Monoid r, Foldable f) => Effect r m -> f a -> n a+choose p as = operation p $ \k -> ala' WrapMonad foldMap k as++dfs :: (Monad m, Monoid r) => (a -> r) -> Handler r r m a+dfs f = Handler+  { ret = return . f+  , fin = return+  }++set :: (Monad m, Ord a) => Handler (Set.Set a) (Set.Set a) m a+set = dfs Set.singleton++alternatives :: (Monad m, Alternative f) => Handler (WrappedAlt f a) (f a) m a+alternatives = accumulate (WrapAlt . pure)++accumulate :: (Monad m, Newtype n o) => (a -> n) -> Handler n o m a+accumulate f = Handler+  { ret = return . f+  , fin = return . unpack+  }++newtype BFS r = BFS { unBFS :: Int -> Maybe r }+instance Monoid r => Monoid (BFS r) where+  mempty                = BFS $ \d -> if d == 0 then Just mempty else Nothing+  BFS f `mappend` BFS g = BFS $ \d -> if d == 0 then f d else f d `mappend` g (d - 1)+instance Monoid r => Newtype (BFS r) r where+  pack r                = BFS $ \d -> if d == 0 then Just r else Nothing+  unpack (BFS f)        = loop 0 where loop d = maybe mempty (`mappend` loop (d + 1)) (f d)++bfs :: (Monad m, Monoid r) => (a -> r) -> Handler (BFS r) r m a+bfs f = accumulate (pack . f)
− src/Control/Effects/Set.hs
@@ -1,17 +0,0 @@-{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-}-module Control.Effects.Set where--import Control.Effects-import qualified Data.Set as Set--choose :: (c ~ ContT (Set.Set r) m, AutoLift c n, Monad m, Ord r) -       => Proxy c -> [a] -> n a-choose p as = operation p $ \k -> do-  sets <- mapM k as-  return $ Set.unions sets--set :: (Monad m, Ord a) => Handler (Set.Set a) (Set.Set a) m a-set = Handler-  { ret = return . Set.singleton-  , fin = return-  }
src/Control/Effects/State.hs view
@@ -1,15 +1,34 @@-{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-}+{-# LANGUAGE FlexibleContexts #-} module Control.Effects.State where  import Control.Effects -get :: (c ~ ContT (s -> m r) m, AutoLift c n, Monad m) => Proxy c -> n s+type State s m a = s -> m a++get :: AutoLift (State s m a) m n => Effect (State s m a) m -> n s get p = operation p $ \k -> return $ \s -> do r <- k s; r s -put :: (c ~ ContT (s -> m r) m, AutoLift c n, Monad m) => Proxy c -> s -> n ()-put p s' = operation p $ \k -> return $ \_ -> do r <- k (); r s'+put :: AutoLift (State s m a) m n => Effect (State s m a) m -> s -> n ()+put p s = operation p $ \k -> return $ \_ -> do r <- k (); r s -ref :: Monad m => s -> Handler (s -> m a) a m a+infixr 3 =:+(=:) :: AutoLift (State s m a) m n => Effect (State s m a) m -> n s -> n ()+p =: m = m >>= put p++modify :: AutoLift (State s m a) m n => Effect (State s m a) m -> (s -> s) -> n ()+modify p f = do+  v <- get p+  put p (f v)++local :: AutoLift (State s m a) m n => Effect (State s m a) m -> (s -> s) -> n b -> n b+local p f m = do+  v <- get p+  put p (f v)+  r <- m+  put p v+  return r++ref :: Monad m => s -> Handler (State s m a) a m a ref s_init = Handler   { ret = return . return . return   , fin = \f -> f s_init
src/Control/Effects/Writer.hs view
@@ -1,11 +1,13 @@-{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-}+{-# LANGUAGE FlexibleContexts #-} module Control.Effects.Writer where  import Control.Effects import Data.Monoid -tell :: (c ~ ContT (w, r) m, AutoLift c n, Monad m, Monoid w) => Proxy c -> w -> n ()-tell p w = operation p $ \k -> do (w', r) <- k (); return (w `mappend` w', r)+tell :: (AutoLift (w, r) m n, Monoid w) => Effect (w, r) m -> w -> n ()+tell p v = operation p $ \k -> do+  ~(w, r) <- k ()+  return (mappend v w, r)  writer :: (Monad m, Monoid w) => Handler (w, a) (w, a) m a writer = Handler