packages feed

simple-effects 0.11.0.1 → 0.12.0.0

raw patch · 16 files changed

+168/−177 lines, 16 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Control.Effects: data family EffMethods e (m :: * -> *) :: *;
- Control.Effects.Early: data Early a
- Control.Effects.List: data NonDeterminism
- Control.Effects.Reader: data ReadEnv e
- Control.Effects.Reader: instance GHC.Generics.Generic (Control.Effects.EffMethods (Control.Effects.Reader.ReadEnv e) m)
- Control.Effects.Resource: data Bracket
- Control.Effects.Resource: instance Control.Effects.Resource.Unexceptional ListT.ListT
- Control.Effects.Signal: data HandleException e
- Control.Effects.Signal: data Signal a b
- Control.Effects.Signal: instance GHC.Generics.Generic (Control.Effects.EffMethods (Control.Effects.Signal.Signal a b) m)
- Control.Effects.State: instance GHC.Generics.Generic (Control.Effects.EffMethods (Control.Effects.State.State s) m)
- Control.Effects.Yield: data Yield a
- Control.Effects.Yield: instance GHC.Generics.Generic (Control.Effects.EffMethods (Control.Effects.Yield.Yield a) m)
+ Control.Effects.Async: AsyncMethods :: (forall a. m a -> m (AsyncThread m a)) -> (forall a. AsyncThread m a -> m a) -> Async m
+ Control.Effects.Async: [_async] :: Async m -> forall a. m a -> m (AsyncThread m a)
+ Control.Effects.Async: [_waitAsync] :: Async m -> forall a. AsyncThread m a -> m a
+ Control.Effects.Early: EarlyMethods :: (forall b. a -> m b) -> Early a m
+ Control.Effects.Early: [_earlyReturn] :: Early a m -> forall b. a -> m b
+ Control.Effects.Early: newtype Early a m
+ Control.Effects.List: NonDeterminismMethods :: (forall a. [a] -> m a) -> NonDeterminism m
+ Control.Effects.List: [_choose] :: NonDeterminism m -> forall a. [a] -> m a
+ Control.Effects.List: newtype NonDeterminism m
+ Control.Effects.Reader: ReadEnvMethods :: m e -> ReadEnv e m
+ Control.Effects.Reader: [_readEnv] :: ReadEnv e m -> m e
+ Control.Effects.Reader: instance GHC.Generics.Generic (Control.Effects.Reader.ReadEnv e m)
+ Control.Effects.Reader: newtype ReadEnv e m
+ Control.Effects.Resource: BracketMethods :: (forall resource result cleanupRes. m resource -> (resource -> Maybe result -> m cleanupRes) -> (resource -> m result) -> m result) -> Bracket m
+ Control.Effects.Resource: [_bracket] :: Bracket m -> forall resource result cleanupRes. m resource -> (resource -> Maybe result -> m cleanupRes) -> (resource -> m result) -> m result
+ Control.Effects.Resource: newtype Bracket m
+ Control.Effects.Signal: HandleExceptionMethods :: (forall a. (e -> m a) -> m a -> m a) -> HandleException e m
+ Control.Effects.Signal: SignalMethods :: (a -> m b) -> Signal a b m
+ Control.Effects.Signal: [_handleWithoutDiscarding] :: HandleException e m -> forall a. (e -> m a) -> m a -> m a
+ Control.Effects.Signal: [_signal] :: Signal a b m -> a -> m b
+ Control.Effects.Signal: instance GHC.Generics.Generic (Control.Effects.Signal.Signal a b m)
+ Control.Effects.Signal: newtype HandleException e m
+ Control.Effects.Signal: newtype Signal a b m
+ Control.Effects.State: StateMethods :: m s -> (s -> m ()) -> State s m
+ Control.Effects.State: [_getState] :: State s m -> m s
+ Control.Effects.State: [_setState] :: State s m -> s -> m ()
+ Control.Effects.State: instance GHC.Generics.Generic (Control.Effects.State.State s m)
+ Control.Effects.Yield: YieldMethods :: (a -> m ()) -> Yield a m
+ Control.Effects.Yield: [_yield] :: Yield a m -> a -> m ()
+ Control.Effects.Yield: instance GHC.Generics.Generic (Control.Effects.Yield.Yield a m)
+ Control.Effects.Yield: newtype Yield a m
- Control.Effects: RuntimeImplemented :: ReaderT (EffMethods e m) m a -> RuntimeImplemented e m a
+ Control.Effects: RuntimeImplemented :: ReaderT (e m) m a -> RuntimeImplemented e m a
- Control.Effects: [getRuntimeImplemented] :: RuntimeImplemented e m a -> ReaderT (EffMethods e m) m a
+ Control.Effects: [getRuntimeImplemented] :: RuntimeImplemented e m a -> ReaderT (e m) m a
- Control.Effects: class Effect e where {
+ Control.Effects: class Effect (e :: (* -> *) -> *) where {
- Control.Effects: effect :: (MonadEffect e m, MonadEffect e m', Monad (t m'), CanLift e t, t m' ~ m) => EffMethods e m
+ Control.Effects: effect :: (MonadEffect e m, MonadEffect e m', Monad (t m'), CanLift e t, t m' ~ m) => e m
- Control.Effects: implement :: forall e m a. EffMethods e m -> RuntimeImplemented e m a -> m a
+ Control.Effects: implement :: forall e m a. e m -> RuntimeImplemented e m a -> m a
- Control.Effects: liftThrough :: forall t m. (Effect e, Generic (EffMethods e m), MonadTrans t, Monad m, Monad (t m), SimpleMethods (EffMethods e) m t) => EffMethods e m -> EffMethods e (t m)
+ Control.Effects: liftThrough :: forall t m. (Effect e, Generic (e m), MonadTrans t, Monad m, Monad (t m), SimpleMethods e m t) => e m -> e (t m)
- Control.Effects: mergeContext :: (Effect e, Generic (EffMethods e m), MonadicMethods (EffMethods e) m) => m (EffMethods e m) -> EffMethods e m
+ Control.Effects: mergeContext :: (Effect e, Generic (e m), MonadicMethods e m) => m (e m) -> e m
- Control.Effects.Async: data Async
+ Control.Effects.Async: data Async m
- Control.Effects.Generic: genericLiftThrough :: forall t e em m. (MonadTrans t, Monad m, Monad (t m), SimpleMethods (em e) m t) => em e m -> em e (t m)
+ Control.Effects.Generic: genericLiftThrough :: forall t e m. (MonadTrans t, Monad m, Monad (t m), SimpleMethods e m t) => e m -> e (t m)
- Control.Effects.State: data State s
+ Control.Effects.State: data State s m

Files

simple-effects.cabal view
@@ -1,5 +1,5 @@ name:                simple-effects
-version:             0.11.0.1
+version:             0.12.0.0
 synopsis:            A simple effect system that integrates with MTL
 description:         Please see the tutorial modules
 homepage:            https://gitlab.com/LukaHorvat/simple-effects
src/Control/Effects.hs view
@@ -11,29 +11,28 @@ import Control.Effects.Generic
 import GHC.Generics
 
-class Effect e where
-    data EffMethods e (m :: * -> *) :: *
+class Effect (e :: (* -> *) -> *) where
     type CanLift e (t :: (* -> *) -> * -> *) :: Constraint
     type CanLift e t = MonadTrans t
     liftThrough ::
         forall t m. (CanLift e t, Monad m, Monad (t m))
-        => EffMethods e m -> EffMethods e (t m)
+        => e m -> e (t m)
     default liftThrough ::
         forall t m.
-        ( Generic (EffMethods e m), MonadTrans t, Monad m, Monad (t m)
-        , SimpleMethods (EffMethods e) m t )
-        => EffMethods e m -> EffMethods e (t m)
+        ( Generic (e m), MonadTrans t, Monad m, Monad (t m)
+        , SimpleMethods e m t )
+        => e m -> e (t m)
     liftThrough = genericLiftThrough
 
-    mergeContext :: Monad m => m (EffMethods e m) -> EffMethods e m
+    mergeContext :: Monad m => m (e m) -> e m
     default mergeContext ::
-        (Generic (EffMethods e m), MonadicMethods (EffMethods e) m)
-        => m (EffMethods e m) -> EffMethods e m
+        (Generic (e m), MonadicMethods e m)
+        => m (e m) -> e m
     mergeContext = genericMergeContext
 
 class (Effect e, Monad m) => MonadEffect e m where
-    effect :: EffMethods e m
-    default effect :: (MonadEffect e m', Monad (t m'), CanLift e t, t m' ~ m) => EffMethods e m
+    effect :: e m
+    default effect :: (MonadEffect e m', Monad (t m'), CanLift e t, t m' ~ m) => e m
     effect = liftThrough effect
 
 instance {-# OVERLAPPABLE #-}
@@ -42,7 +41,7 @@     effect = liftThrough effect
 
 newtype RuntimeImplemented e m a = RuntimeImplemented
-    { getRuntimeImplemented :: ReaderT (EffMethods e m) m a }
+    { getRuntimeImplemented :: ReaderT (e m) m a }
     deriving
         ( Functor, Applicative, Monad, MonadPlus, Alternative, MonadState s, MonadIO, MonadCatch
         , MonadThrow, MonadRandom, MonadMask )
@@ -56,13 +55,13 @@ 
 deriving instance MonadBase b m => MonadBase b (RuntimeImplemented e m)
 instance MonadBaseControl b m => MonadBaseControl b (RuntimeImplemented e m) where
-    type StM (RuntimeImplemented e m) a = StM (ReaderT (EffMethods e m) m) a
+    type StM (RuntimeImplemented e m) a = StM (ReaderT (e m) m) a
     liftBaseWith f = RuntimeImplemented $ liftBaseWith $ \q -> f (q . getRuntimeImplemented)
     restoreM = RuntimeImplemented . restoreM
 
 instance RunnableTrans (RuntimeImplemented e) where
     type TransformerResult (RuntimeImplemented e) a = a
-    type TransformerState (RuntimeImplemented e) m = EffMethods e m
+    type TransformerState (RuntimeImplemented e) m = e m
     currentTransState = RuntimeImplemented ask
     restoreTransState = return
     runTransformer (RuntimeImplemented m) = runReaderT m
@@ -71,7 +70,7 @@     => MonadEffect e (RuntimeImplemented e m) where
     effect = mergeContext $ RuntimeImplemented (liftThrough <$> ask)
 
-implement :: forall e m a. EffMethods e m -> RuntimeImplemented e m a -> m a
+implement :: forall e m a. e m -> RuntimeImplemented e m a -> m a
 implement em (RuntimeImplemented r) = runReaderT r em
 
 type family MonadEffects effs m :: Constraint where
src/Control/Effects/Async.hs view
@@ -14,10 +14,10 @@ import Control.Effects
 import qualified Control.Concurrent.Async as Async
 import Control.Monad.Runnable
-import Control.Effects.State
 
--- | The name of the effect
-data Async
+data Async m = AsyncMethods
+    { _async :: forall a. m a -> m (AsyncThread m a)
+    , _waitAsync :: forall a. AsyncThread m a -> m a }
 
 -- | The type that represents the forked computation in the monad @m@ that eventually computes
 --   a value of type @a@. Depending on the monad, the computation may produce zero, one or even
@@ -26,9 +26,6 @@     deriving (Functor, Eq, Ord)
 
 instance Effect Async where
-    data EffMethods Async m = AsyncMethods
-        { _async :: forall a. m a -> m (AsyncThread m a)
-        , _waitAsync :: forall a. AsyncThread m a -> m a }
     type CanLift Async t = RunnableTrans t
     mergeContext mm = AsyncMethods
         (\a -> mm >>= ($ a) . _async)
@@ -83,4 +80,4 @@ --   The functions doesn't actually do anything, the real implementation is given by the
 --   @'MonadEffect' 'Async' IO@ instance which uses the @async@ package.
 implementAsyncViaIO :: IO a -> IO a
-implementAsyncViaIO = id+implementAsyncViaIO = id
src/Control/Effects/Early.hs view
@@ -30,7 +30,7 @@ --
 --   You can use the 'earlyReturn' function directly, or one of the helpers for common use cases.
 module Control.Effects.Early
-    ( module Control.Effects, Early, EffMethods(..)
+    ( module Control.Effects, Early(..)
     , earlyReturn, handleEarly, onlyDo, ifNothingEarlyReturn, ifNothingDo
     , ifLeftEarlyReturn, ifLeftDo ) where
 
@@ -39,15 +39,14 @@ import Control.Effects
 
 newtype EarlyValue a = EarlyValue { getEarlyValue :: a }
-data Early a
+newtype Early a m = EarlyMethods
+    { _earlyReturn :: forall b. a -> m b }
 instance Effect (Early a) where
-    data EffMethods (Early a) m = EarlyMethods
-        { _earlyReturn :: forall b. a -> m b }
     liftThrough (EarlyMethods f) = EarlyMethods (lift . f)
     mergeContext m = EarlyMethods (\a -> do
         f <- _earlyReturn <$> m
         f a)
-    
+
 instance (Monad m, a ~ b) => MonadEffect (Early a) (ExceptT (EarlyValue b) m) where
     effect = EarlyMethods (throwE . EarlyValue)
 
src/Control/Effects/Generic.hs view
@@ -15,12 +15,12 @@ class (Generic (a m), Generic (a (t m)), Generic (a M)) => SimpleMethods a m t where
     liftSimple :: a m -> a (t m)
 
-instance 
+instance
     ( Rep (a m) ~ D1 m1 (C1 m2 p)
     , Rep (a M) ~ D1 m1 (C1 m2 pM)
     , Rep (a (t m)) ~ D1 m1 (C1 m2 (LiftedProducts p pM m t))
     , ProductOfSimpleMethods p pM m t
-    , Generic (a m), Generic (a (t m)), Generic (a M) ) 
+    , Generic (a m), Generic (a (t m)), Generic (a M) )
     => SimpleMethods a m t where
     liftSimple a = case Gen.from a of
         M1 (M1 p) -> Gen.to (M1 (M1 (liftProducts (Proxy @m) (Proxy @t) (Proxy @pM) p)))
@@ -31,19 +31,19 @@     liftProducts :: Proxy m -> Proxy t -> Proxy pM -> p x -> LiftedProducts p pM m t x
 
 instance SimpleMethod f fM m t => ProductOfSimpleMethods (S1 m1 (Rec0 f)) (S1 m1 (Rec0 fM)) m t where
-    type LiftedProducts (S1 m1 (Rec0 f)) (S1 m1 (Rec0 fM)) m t = 
+    type LiftedProducts (S1 m1 (Rec0 f)) (S1 m1 (Rec0 fM)) m t =
         (S1 m1 (Rec0 (LiftedMethod f fM m t)))
     liftProducts p1 p2 _ (M1 (K1 f)) = M1 (K1 (liftMethod p1 p2 (Proxy @fM) f))
     {-# INLINE liftProducts #-}
-instance 
-    (ProductOfSimpleMethods f1 f1M m t, ProductOfSimpleMethods f2 f2M m t)  
+instance
+    (ProductOfSimpleMethods f1 f1M m t, ProductOfSimpleMethods f2 f2M m t)
     => ProductOfSimpleMethods (f1 :*: f2) (f1M :*: f2M) m t where
-    type LiftedProducts (f1 :*: f2) (f1M :*: f2M) m t = 
+    type LiftedProducts (f1 :*: f2) (f1M :*: f2M) m t =
         LiftedProducts f1 f1M m t :*: LiftedProducts f2 f2M m t
-    liftProducts p1 p2 _ (f1 :*: f2) = 
-        liftProducts p1 p2 (Proxy @f1M) f1 :*: liftProducts p1 p2 (Proxy @f2M) f2 
+    liftProducts p1 p2 _ (f1 :*: f2) =
+        liftProducts p1 p2 (Proxy @f1M) f1 :*: liftProducts p1 p2 (Proxy @f2M) f2
     {-# INLINE liftProducts #-}
-    
+
 class (MonadTrans t, Monad m) => SimpleMethod f fM (m :: * -> *) (t :: (* -> *) -> * -> *) where
     type LiftedMethod f fM m t
     liftMethod :: Proxy m -> Proxy t -> Proxy fM -> f -> LiftedMethod f fM m t
@@ -58,26 +58,26 @@     liftMethod p1 p2 _ f a = liftMethod p1 p2 (Proxy @bM) (f a :: b)
     {-# INLINE liftMethod #-}
 instance {-# OVERLAPPABLE #-}
-    ( TypeError ('Text "Effect methods must be monadic actions or functions resulting in monadic actions") 
+    ( TypeError ('Text "Effect methods must be monadic actions or functions resulting in monadic actions")
     , Monad m, MonadTrans t )
     => SimpleMethod a b m t
 
 class IndependentOfM (a :: k) (m :: * -> *) where
-instance 
-    (IndependentOfM a m, IndependentOfM b m) 
+instance
+    (IndependentOfM a m, IndependentOfM b m)
     => IndependentOfM (a b) m
-instance 
-    TypeError 
-        ('Text "Parameters of methods can't depend on the monadic context (" 
-        ':<>: 'ShowType m 
+instance
+    TypeError
+        ('Text "Parameters of methods can't depend on the monadic context ("
+        ':<>: 'ShowType m
         ':<>: 'Text ")")
     => IndependentOfM M m
 instance {-# OVERLAPPABLE #-}
     IndependentOfM (a :: k) m
 
 genericLiftThrough ::
-    forall t e em m. (MonadTrans t, Monad m, Monad (t m), SimpleMethods (em e) m t)
-    => em e m -> em e (t m)
+    forall t e m. (MonadTrans t, Monad m, Monad (t m), SimpleMethods e m t)
+    => e m -> e (t m)
 genericLiftThrough = liftSimple
 {-# INLINE genericLiftThrough #-}
 
@@ -85,11 +85,11 @@ 
 class MonadicMethods a m where
     mergeMonadicMethods :: m (a m) -> a m
-instance 
+instance
     ( Rep (a m) ~ D1 m1 (C1 m2 p)
     , Rep (a M) ~ D1 m1 (C1 m2 pM)
     , ProductOfMonadicMethods p pM a m
-    , Generic (a m), Generic (a M) ) 
+    , Generic (a m), Generic (a M) )
     => MonadicMethods a m where
     mergeMonadicMethods a = Gen.to (M1 (M1 (mergeMonadicProducts (Proxy @p) (Proxy @pM) a f)))
         where
@@ -103,11 +103,11 @@         where
         g (M1 (K1 x)) = x
     {-# INLINE mergeMonadicProducts #-}
-instance 
-    (ProductOfMonadicMethods f1 f1M a m, ProductOfMonadicMethods f2 f2M a m)  
+instance
+    (ProductOfMonadicMethods f1 f1M a m, ProductOfMonadicMethods f2 f2M a m)
     => ProductOfMonadicMethods (f1 :*: f2) (f1M :*: f2M) a m where
-    mergeMonadicProducts _ _ ma f = 
-        mergeMonadicProducts (Proxy @f1) (Proxy @f1M) ma (g1 . f) 
+    mergeMonadicProducts _ _ ma f =
+        mergeMonadicProducts (Proxy @f1) (Proxy @f1M) ma (g1 . f)
         :*: mergeMonadicProducts (Proxy @f2) (Proxy @f2M) ma (g2 . f)
         where
         g1 (x :*: _) = x
@@ -127,10 +127,10 @@         g = ($ b)
     {-# INLINE mergeMethod #-}
 instance {-# OVERLAPPABLE #-}
-    ( TypeError ('Text "Effect methods must be monadic actions or functions resulting in monadic actions") 
+    ( TypeError ('Text "Effect methods must be monadic actions or functions resulting in monadic actions")
     , Monad m )
     => MonadicMethod a f fM m
 
 genericMergeContext :: MonadicMethods a m => m (a m) -> a m
 genericMergeContext = mergeMonadicMethods
-{-# INLINE genericMergeContext #-}+{-# INLINE genericMergeContext #-}
src/Control/Effects/List.hs view
@@ -12,10 +12,9 @@ 
 import Control.Effects
 
-data NonDeterminism
+newtype NonDeterminism m = NonDeterminismMethods
+    { _choose :: forall a. [a] -> m a }
 instance Effect NonDeterminism where
-    data EffMethods NonDeterminism m = NonDeterminismMethods
-        { _choose :: forall a. [a] -> m a }
     liftThrough (NonDeterminismMethods c) = NonDeterminismMethods (lift . c)
     mergeContext m = NonDeterminismMethods (\a -> do
         lm <- m
@@ -63,4 +62,4 @@ 
 -- | Execute all the effects but discard their results.
 evaluateAll :: Monad m => ListT m a -> m ()
-evaluateAll = void . evaluateToList+evaluateAll = void . evaluateToList
src/Control/Effects/Reader.hs view
@@ -15,11 +15,10 @@ import Control.Effects
 import GHC.Generics
 
-data ReadEnv e
-instance Effect (ReadEnv e) where
-    data EffMethods (ReadEnv e) m = ReadEnvMethods
-        { _readEnv :: m e }
-        deriving (Generic)
+newtype ReadEnv e m = ReadEnvMethods
+    { _readEnv :: m e }
+    deriving (Generic)
+instance Effect (ReadEnv e)
 
 -- | Read a value of type 'e'. Use with the TypeApplications extension to
 --   help with type inference
src/Control/Effects/Resource.hs view
@@ -24,15 +24,17 @@ -- Counter-examples: @'ExceptT' e@, @'ErrorT' e@, 'MaybeT', 'ListT'
 class Unexceptional (t :: (* -> *) -> * -> *)
 
-data Bracket
+newtype Bracket m = BracketMethods
+    { _bracket ::
+        forall resource result cleanupRes.
+        m resource
+        -> (resource -> Maybe result -> m cleanupRes)
+        -> (resource -> m result)
+        -> m result }
 instance Effect Bracket where
-    data EffMethods Bracket m = BracketMethods
-        { _bracket ::
-            forall resource result cleanupRes.
-            m resource -> (resource -> Maybe result -> m cleanupRes) -> (resource -> m result) -> m result }
     type CanLift Bracket t = (RunnableTrans t, Unexceptional t)
     liftThrough :: forall m t. (RunnableTrans t, Monad (t m), Monad m)
-        => EffMethods Bracket m -> EffMethods Bracket (t m)
+        => Bracket m -> Bracket (t m)
     liftThrough (BracketMethods f) = BracketMethods g
         where
         g :: forall a b c. t m a -> (a -> Maybe c -> t m b) -> (a -> t m c) -> t m c
@@ -133,7 +135,6 @@ instance Unexceptional (LR.RWST r w s)
 instance Unexceptional IdentityT
 instance Unexceptional (ReaderT r)
-instance Unexceptional ListT
 instance Unexceptional (RuntimeImplemented e)
 
 -- | A simpler version of 'bracket' that doesn't use the results of the parameters.
src/Control/Effects/Signal.hs view
@@ -9,11 +9,11 @@ --   will be the result /of calling the 'signal' function/. This effectively allows you to have
 --   recoverable exceptions at the throw site, instead of just at the handling site.
 module Control.Effects.Signal
-    ( ResumeOrBreak(..), Signal, throwSignal, handleSignal
+    ( ResumeOrBreak(..), Signal(..), throwSignal, handleSignal
     , Throw, handleException, handleToEither, module Control.Effects
     , module Control.Monad.Trans.Except, MaybeT(..), discardAllExceptions, showAllExceptions
-    , HandleException, handleWithoutDiscarding, handleToEitherRecursive, SomeSignal, signal
-    , EffMethods(..) ) where
+    , HandleException(..), handleWithoutDiscarding, handleToEitherRecursive, SomeSignal
+    , signal ) where
 
 import Import hiding (liftThrough)
 import Control.Monad.Trans.Except
@@ -23,11 +23,10 @@ import Control.Monad.Runnable
 import GHC.Generics
 
-data Signal a b
+newtype Signal a b m = SignalMethods
+    { _signal :: a -> m b }
+    deriving (Generic)
 instance Effect (Signal a b) where
-    data EffMethods (Signal a b) m = SignalMethods
-        { _signal :: a -> m b }
-        deriving (Generic)
 
 signal :: forall a b m. MonadEffect (Signal a b) m => a -> m b
 SignalMethods signal = effect
@@ -58,7 +57,7 @@ type Throw e = Signal e Void
 
 -- | The handle function will return a value of this type.
-data ResumeOrBreak b c = 
+data ResumeOrBreak b c =
     Resume b -- ^ Give a value to the caller of 'signal' and keep going.
     | Break c -- ^ Continue the execution after the handler. The handler will return this value
 
@@ -116,14 +115,13 @@ showAllExceptions :: Functor m => ExceptT SomeSignal m a -> m (Either Text a)
 showAllExceptions = fmap (mapLeft getSomeSignal) . runExceptT
 
-data HandleException e
+newtype HandleException e m = HandleExceptionMethods
+    { _handleWithoutDiscarding :: forall a. (e -> m a) -> m a -> m a  }
 instance Effect (HandleException e) where
-    data EffMethods (HandleException e) m = HandleExceptionMethods
-        { _handleWithoutDiscarding :: forall a. (e -> m a) -> m a -> m a  }
     type CanLift (HandleException e) t = RunnableTrans t
     liftThrough ::
         forall t m. (CanLift (HandleException e) t, Monad m, Monad (t m))
-        => EffMethods (HandleException e) m -> EffMethods (HandleException e) (t m)
+        => HandleException e m -> HandleException e (t m)
     liftThrough (HandleExceptionMethods rec') = HandleExceptionMethods $ \f e -> do
         st <- currentTransState
         res <- lift (rec' (\ex -> runTransformer (f ex) st) (runTransformer e st))
@@ -136,7 +134,7 @@ --   You'll want to use this if you're writing a recursive function. Using the regular handlers
 --   in that case will result with infinite types.
 --
---   Since this function doesn't discard constraints, you still need to handle the exception on 
+--   Since this function doesn't discard constraints, you still need to handle the exception on
 --   the whole computation.
 --
 --   Here's a slightly contrived example.
@@ -157,12 +155,12 @@ -- occured or it preserves all of them up to the point of the exception.
 -- Handling exceptions last and handling them first will produce the former and latter
 -- behaviour respectively.
-handleWithoutDiscarding :: 
+handleWithoutDiscarding ::
     forall e m a. MonadEffect (HandleException e) m => (e -> m a) -> m a -> m a
 HandleExceptionMethods handleWithoutDiscarding = effect
 
 instance Monad m => MonadEffect (HandleException e) (ExceptT e m) where
-    effect = HandleExceptionMethods $ \f -> 
+    effect = HandleExceptionMethods $ \f ->
         ExceptT . (either (runExceptT . f) (return . Right) <=< runExceptT)
 
 -- | 'handleToEither' that doesn't discard 'Throws' constraints. See documentation for
src/Control/Effects/State.hs view
@@ -21,13 +21,11 @@ 
 import Control.Effects
 
-data State s
-
+data State s m = StateMethods
+    { _getState :: m s
+    , _setState :: s -> m () }
+    deriving (Generic)
 instance Effect (State s) where
-    data EffMethods (State s) m = StateMethods
-        { _getState :: m s
-        , _setState :: s -> m () }
-        deriving (Generic)
 
 -- | Get current value of the state with the type 's'.
 -- You can use type applications to tell the type checker which type of state you want.
@@ -52,16 +50,16 @@     effect = StateMethods get put
 
 -- | Implement the state effect via the StateT transformer. If you have a function with a type like
--- @f :: MonadEffect (State Int) m => m ()@ you can use 'implementStateViaStateT' to satisfy the 
+-- @f :: MonadEffect (State Int) m => m ()@ you can use 'implementStateViaStateT' to satisfy the
 -- 'MonadEffect' constraint.
 --
 -- @implementStateViaStateT \@Int 0 f :: Monad m => m ()@
 implementStateViaStateT :: forall s m a. Monad m => s -> StateT s m a -> m a
-implementStateViaStateT = flip evalStateT 
+implementStateViaStateT = flip evalStateT
 
 -- | Handle the state requirement using an 'IORef'. If you have a function with a type like
--- @f :: MonadEffect (State Int) m => m ()@ you can use 'implementStateViaIORef' to replace the 
--- 'MonadEffect' constraint with 'MonadIO'. This is convenient if you already have a 'MonadIO' 
+-- @f :: MonadEffect (State Int) m => m ()@ you can use 'implementStateViaIORef' to replace the
+-- 'MonadEffect' constraint with 'MonadIO'. This is convenient if you already have a 'MonadIO'
 -- constraint and you don't want to use the 'StateT' transformer for some reason.
 --
 -- @implementStateViaIORef \@Int 0 f :: MonadIO m => m ()@
@@ -70,4 +68,3 @@     ref <- liftIO (newIORef initial)
     m & implement (StateMethods (liftIO (readIORef  ref)) (liftIO . writeIORef ref))
 {-# INLINE implementStateViaIORef #-}
-
src/Control/Effects/Yield.hs view
@@ -18,12 +18,10 @@ import Control.Concurrent.MVar
 import Control.Concurrent.Chan
 
-data Yield a
-
-instance Effect (Yield a) where
-    data EffMethods (Yield a) m = YieldMethods
-        { _yield :: a -> m () }
-        deriving (Generic)
+newtype Yield a m = YieldMethods
+    { _yield :: a -> m () }
+    deriving (Generic)
+instance Effect (Yield a)
 
 -- | Output a value of type @a@. The semantics are determined by the implementation, but usually this
 --   will block until the next value is requested by the consumer.
@@ -125,4 +123,4 @@ traverseYielded_ :: Monad m => m (Maybe a) -> (a -> m b) -> m ()
 traverseYielded_ m f = m >>= \case
     Nothing -> return ()
-    Just a -> f a >> traverseYielded_ m f+    Just a -> f a >> traverseYielded_ m f
src/Control/Monad/Runnable.hs view
@@ -45,12 +45,27 @@ 
 -- | A class of transformers that can run their effects in the underlying monad.
 --
---   The following law needs to hold.
+-- The following laws need to hold:
 --
--- @
---   f :: (forall a. m a -> m a)
---   \\m s -> runTransformer (lift (f m)) s == \\m s -> f (runTransformer (lift m) s)
--- @
+-- [1]
+--     Running a computation that only uses the effects /of the transformer/ (represented here
+--     by stating that the computation is polymorphic in the underlying monad) using the current
+--     state, and then restoring the result is the same as doing nothing.
+--
+--     @
+--     t :: forall m. Monad m => t m a
+--     t == (currentTransState >>= lift . runTransformer t >>= restoreTransState)
+--     @
+--
+-- [2]
+--     Running a computation that only uses the effects /of the underlying monad/ (represented here
+--     by stating that the computation is polymorphic in the transformer) using /any/ state, and
+--     then restoring the result is the same as doing nothing.
+--
+--     @
+--     t :: forall t. MonadTrans t => t m a -> t m a
+--     t == (lift (runTransformer t s) >>= restoreTransState)
+--     @
 class MonadTrans t => RunnableTrans t where
     -- | The type of value that needs to be provided to run this transformer.
     type TransformerState t (m :: * -> *) :: *
src/Tutorial/T2_Details.hs view
@@ -104,27 +104,26 @@     The core of every effect is it's 'Effect' instance. Here's how the class is defined:
 
 @
-class 'Effect' e where
-    data 'EffMethods' e (m :: * -> *) :: *
+class 'Effect' (e :: (* -> *) -> *) where
     type 'CanLift' e (t :: (* -> *) -> * -> *) :: 'Constraint'
     type 'CanLift' e t = 'MonadTrans' t
     'liftThrough' ::
         ('CanLift' e t, 'Monad' m, 'Monad' (t m))
-        => 'EffMethods' e m -> 'EffMethods' e (t m)
-    'mergeContext' :: 'Monad' m => m ('EffMethods' e m) -> 'EffMethods' e m
+        => e m -> e (t m)
+    'mergeContext' :: 'Monad' m => m (e m) -> e m
 @
 
-    The 'EffMethods' associated data type is where you specify the functionality that your effect
+    The type @e@ is the name of your effect and it's where you specify the functionality that your effect
     provides. This will be a record of monadic functions. For example, there's how it's instantiated
     for the state effect:
 
 @
-data 'EffMethods' ('State' s) m = 'StateMethods'
+data 'State' s m = 'StateMethods'
     { '_getState' :: m s
     , '_setState' :: s -> m () }
 @
 
-    Then there's the 'CanLift' type. It specifies the constraint that a transformer needs to satisfy
+    Then there's the 'CanLift' associated type. It specifies the constraint that a transformer needs to satisfy
     to be able to lift the effect through it. Usually, 'MonadTrans' is all you need, so that's the
     default instantiation. Some more complicated effects have tighter demands.
 
@@ -165,17 +164,17 @@         '_setState' sm s }
 @
 
-    If these implementations seem pretty mechanical it's because they are. So mechanical, in fact,
+    If these implementations seem pretty mechanical, it's because they are. So mechanical, in fact,
     that in most of the cases you don't even need to write them. Just derive the 'Generic' class
-    for your effect and you get those definitions for free. Here's the actual instance
-    @'Effect' ('State' s)@:
+    for your effect and you get those definitions for free. Here's the definition of the @'State' s@
+    effect:
 
 @
-instance 'Effect' ('State' s) where
-    data 'EffMethods' ('State' s) m = 'StateMethods'
-        { '_getState' :: m s
-        , '_setState' :: s -> m () }
-        deriving ('Generic')
+data 'EffMethods' ('State' s) m = 'StateMethods'
+    { '_getState' :: m s
+    , '_setState' :: s -> m () }
+    deriving ('Generic')
+instance 'Effect' ('State' s)
 @
 
     There are a couple of conditions though. The automatic method deriving only works for what
@@ -198,11 +197,11 @@ 
 @
 class ('Effect' e, 'Monad' m) => 'MonadEffect' e m where
-    'effect' :: 'EffMethods' e m
+    'effect' :: e m
 @
 
-    So it just says that monads that implement the effect @e@ need to provide a record of
-    the effect's methods that work in that monad.
+    So it just says that monads that implement the effect @e@ need to provide an implementation of
+    the effect's methods that works in that monad.
 
     As discussed in the transformers section, there's an
     overlappable instance given for the 'MonadEffect' class. Here it is:
@@ -236,10 +235,10 @@ 
 @
 newtype 'RuntimeImplemented' e m a = 'RuntimeImplemented'
-    { 'getRuntimeImplemented' :: 'ReaderT' ('EffMethods' e m) m a }
+    { 'getRuntimeImplemented' :: 'ReaderT' (e m) m a }
 @
 
-    It's a wrapper around a 'ReaderT' that carries around an @'EffMethods' e m@ record.
+    It's a wrapper around a 'ReaderT' that carries around an @e m@ implementation.
     @'RuntimeImplemented' e@ has a @'MonadEffect' e@ instance defined like this
 
 @
@@ -253,7 +252,7 @@     'implement' function:
 
 @
-'implement' :: forall e m a. 'EffMethods' e m -> 'RuntimeImplemented' e m a -> m a
+'implement' :: forall e m a. e m -> 'RuntimeImplemented' e m a -> m a
 'implement' em ('RuntimeImplemented' r) = 'runReaderT' r em
 @
 
@@ -285,4 +284,4 @@         it just works.
 
     That's pretty much it. In the next part we'll take a look at implementing our own effects.
--}+-}
src/Tutorial/T3_CustomEffects.hs view
@@ -31,35 +31,30 @@     To start off, we'll define an effect for working with the filesystem. To keep it simple, we'll
     define two functions. One for reading the contents of a file, and one for writing them to a file.
 
-    The first step is to make a name for our effect. Say, @Files@ for example. We declare an empty
-    datatype with that name:
+    The first step is to declare a new record data type that holds the methods of our effect.
+    The signatures of our functions will be @'FilePath' -> m 'ByteString'@ and
+    @'FilePath' -> 'ByteString' -> m ()@ respectively.
 
 @
-data Files
+data Files m = FilesMethods
+    { _readFile :: 'FilePath' -> m 'ByteString'
+    , _writeFile :: 'FilePath' -> 'ByteString' -> m () }
+    deriving ('Generic')
 @
 
     Next, we need to provide an instance of the 'Effect' class for our effect.
 
-    The signatures of our functions will be @'FilePath' -> m 'ByteString'@ and
-    @'FilePath' -> 'ByteString' -> m ()@ respectively. Both of them are methods of what we call, in the
+    Both of our methods are what we call, in the
     jargon of this library, a simple effect. It means that they are functions that return a monadic
     action, and that their arguments don't depend on that monad. As an example, @m Int -> m Int@
     isn't a method of a simple effect because the argument depends on @m@.
-
     Because of this fact, the instance is super simple:
 
 @
-instance 'Effect' Files where
-    data 'EffMethods' Files m = FilesMethods
-        { _readFile :: 'FilePath' -> m 'ByteString'
-        , _writeFile :: 'FilePath' -> 'ByteString' -> m () }
-        deriving ('Generic')
+instance 'Effect' Files
 @
 
-    The 'Effect' class requires you to provide a record of methods for your effect. This is done
-    with an associated data type. You can read about them here
-    <https://wiki.haskell.org/GHC/Type_families#Associated_family_declarations>
-    The class also has two functions: 'liftThrough' and 'mergeContext'. Luckily, because our effect
+    The class has two functions: 'liftThrough' and 'mergeContext'. Luckily, because our effect
     is simple (and mostly they will be), it's enough to just derive 'Generic' for our type. The
     functions are then defined for us.
 
@@ -72,11 +67,11 @@ FilesMethods readFile writeFile = 'effect'
 @
 
-    So how does this work, and what does it even do? Well, we defined how a record of methods looks
+    So how does this work, and what does it even do? Well, we defined what a record of methods looks like
     for our effect, but how is that record actually constructed? If we wanted to /use/ our methods
     where would we get them from? Enter the 'effect' function. It's type signature is
-    @'MonadEffect' e m => 'EffMethods' e m@. It means that for every monad @m@ which supports the
-    effect @e@, the 'effect' function gives us a record of the effect's methods. Let's say we want
+    @'MonadEffect' e m => e m@. It means that for every monad @m@ which supports the
+    effect @e@, the 'effect' function gives us an implementation of the effect's methods. Let's say we want
     to read the contents of a file. First we'd use the 'effect' function to get the methods of our
     @Files@ effect, then we'd get the @_readFile@ function out of it, and finally we'd use that
     function.
@@ -150,19 +145,18 @@ {- $print
     For our next effect we'll do logging. Just a simple printing function that takes anything
     with a 'Show' instance and logs it somewhere.
+    The signature we want is @print :: ('MonadEffect' Print m, 'Show' a) => a -> m ()@.
 
-    The signature we want is @print :: ('MonadEffect' Print m, 'Show' a) => a -> m ()@. Now here's
+    Now here's
     the main issue. The @a@ variable isn't mentioned anywhere in the effect. After all, we don't
     want a separate effect for each possible type. We want the @Print@ effect to provide printing
     /for all/ types with a 'Show' instance. To this end we'll use the @RankNTypes@ extension and define
     our 'Effect' instance like this:
 
 @
-data Print
-
+newtype Print m = PrintMethods
+    { _print :: forall a. Show a => a -> m () }
 instance 'Effect' Print where
-    data 'EffMethods' Print m = PrintMethods
-        { _print :: forall a. Show a => a -> m () }
 @
 
     Notice we didn't derive 'Generic'. This is because we can't. Despite our effect being simple
@@ -174,13 +168,13 @@     The two functions are
 
 @
-'liftThrough' :: ('MonadTrans' t, 'Monad' m, 'Monad' (t m)) => 'EffMethods' e m -> 'EffMethods' e (t m)
+'liftThrough' :: ('MonadTrans' t, 'Monad' m, 'Monad' (t m)) => e m -> e (t m)
 @
 
     and
 
 @
-'mergeContext' :: 'Monad' m => m ('EffMethods' e m) -> 'EffMethods' e m
+'mergeContext' :: 'Monad' m => m (e m) -> e m
 @
 
     [Note]
@@ -256,11 +250,10 @@     Instead we could have defined the whole thing like this:
 
 @
-data Print
+data Print m = PrintMethods
+    { _printString :: 'String' -> m () }
+    deriving ('Generic')
 instance 'Effect' Print where
-    data 'EffMethods' Print m = PrintMethods
-        { _printString :: 'String' -> m () }
-        deriving ('Generic')
 
 print :: ('MonadEffect' Print m, 'Show' a) => a -> m ()
 print = _printString 'effect' . 'show'
@@ -292,10 +285,9 @@     defining our effect and see where we get stuck:
 
 @
-data Fork
+data Fork m = ForkMethods
+    { _fork :: m () -> m ('Maybe' 'ThreadId') }
 instance 'Effect' Fork where
-    data 'EffMethods' Fork m = ForkMethods
-        { _fork :: m () -> m ('Maybe' 'ThreadId') }
     'mergeContext' mm = ForkMethods
         (\\a -> do
             ForkMethods m <- mm
@@ -318,8 +310,7 @@     @a :: t m ()@ so it seems that we need a function that's opposite of 'lift'. Something like
     @unlift :: t m a -> m a@.
 
-
-    Turns out, that's not so simple to do. Imagine you have a function like with a type @a -> m b@.
+    Turns out, that's not so simple to do. Imagine you have a function of type @a -> m b@.
     In this case the @a ->@ part is @t@. If we specialize @unlift@ to that we get
     @unlift :: (a -> m b) -> m b@. There's no way to implement that function. To get @m b@ we need
     to have an @a@, but none are given to us.
@@ -353,10 +344,9 @@     confusion (or perhaps to introduce more of it) here's the code:
 
 @
-data Fork
+data Fork m = ForkMethods
+    { _fork :: m () -> m ('Maybe' 'ThreadId') }
 instance 'Effect' Fork where
-    data 'EffMethods' Fork m = ForkMethods
-        { _fork :: m () -> m ('Maybe' 'ThreadId') }
     type 'CanLift' Fork t = 'RunnableTrans'  t
     'mergeContext' mm = ForkMethods
         (\\a -> do
@@ -380,7 +370,8 @@         are the final 'IO' ones. The state of the original computation does get shared with the
         forked one, so that's pretty useful, but if we care about what the forked computation /did/
         with that state, we need to communicate with the original thread manually through some 'IO'
-        mechanism like 'MVar's.
+        mechanism like 'MVar's. Check out the 'Async' effect that this library provides for an
+        alternative.
 
     What about the effect handlers? How do we write one for our @Fork@ effect? Here's one that
     ignores completely what the intended semantics were and just runs the thing sequentially:
@@ -416,4 +407,4 @@     As you can see, the function doesn't do anything, but it does force whatever we give it to be
     in the 'IO' monad. This again means that we must handle this effect after all others, but if
     there are other effects with the same requirement, they can all be handled at the end.
--}+-}
src/Tutorial/Test.hs view
@@ -73,10 +73,9 @@             setState . succ =<< getState @Int
         liftIO . print =<< getState @Int
 
-data Fork
+newtype Fork m = ForkMethods
+    { _fork :: m () -> m (Maybe ThreadId) }
 instance Effect Fork where
-    data EffMethods Fork m = ForkMethods
-        { _fork :: m () -> m (Maybe ThreadId) }
     type CanLift Fork t = RunnableTrans  t
     mergeContext mm = ForkMethods
         (\a -> do
@@ -110,4 +109,4 @@     liftIO . print =<< getState @Int
 
 main5 :: IO ()
-main5 = implementStateViaStateT @Int 0 testMethod+main5 = implementStateViaStateT @Int 0 testMethod
test/Main.hs view
@@ -126,7 +126,7 @@         print res
         void getLine
 
-testResource = evaluateAll $ bracket
-    (choose [True, False] >>= \tf -> liftIO (putStrLn ("acq " ++ show tf)) >> return tf)
-    (\tf _ -> liftIO $ putStrLn ("cleaning " ++ show tf))
-    (\tf -> if tf then liftIO $ putStrLn "true" else error "io err" >> liftIO (putStrLn "false") )
+-- testResource = evaluateAll $ bracket
+--     (choose [True, False] >>= \tf -> liftIO (putStrLn ("acq " ++ show tf)) >> return tf)
+--     (\tf _ -> liftIO $ putStrLn ("cleaning " ++ show tf))
+--     (\tf -> if tf then liftIO $ putStrLn "true" else error "io err" >> liftIO (putStrLn "false") )