diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,33 @@
+# v0.5.0.0
+
+- Derives `Generic1` instances for all non-existentially-quantified effect datatypes.
+
+- Derives `Foldable` & `Traversable` instances for `:+:`.
+
+- Defines `MonadFix` instances for all of the carriers.
+
+- Re-exports `run`, `:+:`, and `Member` from `Control.Effect.Carrier`, reducing the number of imports needed when defining new effects.
+
+- Re-exports `Carrier`, `Member`, and `run` from the various effect modules, reducing the number of imports needed when using existing effects.
+
+## Backwards-incompatible changes
+
+- Replaces `runResource` with an equivalent function that uses `MonadUnliftIO` to select the correct unlifting function (a la `withResource`, which is removed in favor of `runResource`).
+
+- Changes the signature of `eff` from `sig m (m a) -> m a` to `sig m a -> m a`, requiring effects to hold `m k` in their continuation positions instead of merely `k`. This was done in order to improve interoperability with other presentations of higher-order syntax, e.g. `bound`; syntax used with `bound` can now be given `HFunctor` and `Carrier` instances.
+
+  To upgrade effects used with previous versions, change any continuations from `k` to `m k`. If no existential type variables appear in the effect, you can derive `Generic1`, and thence `HFunctor` & `Effect` instances. Otherwise, implement the required instances by hand. Since continuation positions now occur in `m`, `hmap` definitions will have to apply the higher-order function to these as well.
+
+- Adds `Functor` constraints to `hmap` and `Monad` constraints to `handle`, allowing a greater variety of instances to be defined (e.g. for recursively-nested syntax).
+
+- Replaces the default definitions of `hmap` and `handle` with derivations based on `Generic1` instead of `Coercible`. Therefore, first-order effects wishing to derive these instances will require `Generic1` instances, presumably derived using `-XDeriveGeneric`.
+
+- Moves `send` from `Control.Effect.Sum` to `Control.Effect.Carrier`. Likewise removes the re-export of `send` from `Control.Effect`.
+
+- Deprecates `fmap'` in favour of `fmap`.
+
+- Deprecates `handlePure` in favour of `hmap`.
+
 # v0.4.0.0
 
 ## Backwards-incompatible changes
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # A fast, flexible, fused effect system for Haskell
 
-[![Build Status](https://travis-ci.com/fused-effects/fused-effects.svg?branch=master)](https://travis-ci.com/fused-effects/fused-effects)
+[![Build Status](https://travis-ci.com/fused-effects/fused-effects.svg?branch=master)](https://travis-ci.com/fused-effects/fused-effects) [![hackage](https://img.shields.io/hackage/v/fused-effects.svg?color=blue&style=popout)](http://hackage.haskell.org/package/fused-effects)
 
 - [Overview][]
   - [Algebraic effects][]
@@ -112,11 +112,11 @@
 ```haskell
 example1 :: (Carrier sig m, Effect sig) => [a] -> m (Int, ())
 example1 list = runState 0 $ do
-  i <- get
+  i <- get @Int
   put (i + length list)
 ```
 
-`runState` returns a tuple of both the computed value (the `()`) and the final state (the `Int`), visible in the result of the returned computation.
+`runState` returns a tuple of both the computed value (the `()`) and the final state (the `Int`), visible in the result of the returned computation. The `get` function is resolved with a visible type application, due to the fact that effects can contain more than one state type (in contrast with `mtl`'s `MonadState`, which limits the user to a single state type).
 
 Since this function returns a value in some carrier `m`, effect handlers can be chained to run multiple effects. Here, we get the list to compute the length of from a `Reader` effect:
 
@@ -127,7 +127,7 @@
   put (length (list :: String))
 ```
 
-(Note that the type annotation on `list` is necessary to disambiguate the requested value, since otherwise all the typechecker knows is that it’s an arbitrary `Foldable`. For more information, see the [comparison to `mtl`](#comparison-to--mtl-).)
+(Note that the type annotation on `list` is necessary to disambiguate the requested value, since otherwise all the typechecker knows is that it’s an arbitrary `Foldable`. For more information, see the [comparison to `mtl`](#comparison-to-mtl).)
 
 When all effects have been handled, a computation’s final value can be extracted with `run`:
 
@@ -154,17 +154,18 @@
 
 ### Required compiler extensions
 
-To use effects, you'll need a relatively-uncontroversial set of extensions: `-XFlexibleContexts`, `-XFlexibleInstances`, and `-XMultiParamTypeClasses`.
+To use effects, you'll typically need `-XFlexibleContexts`.
 
-When defining your own effects, you'll need `-XTypeOperators` to declare a `Carrier` instance over (`:+:`), and `-XUndecidableInstances` to satisfy the coverage condition for this instance. You may need `-XKindSignatures` if GHC cannot correctly infer the type of your handler; see the [documentation on common errors][common] for more information about this case.
+When defining your own effects, you may need `-XKindSignatures` if GHC cannot correctly infer the type of your handler; see the [documentation on common errors][common] for more information about this case. `-XDeriveGeneric` can be used with many first-order effects to derive default implementations of `HFunctor` and `Effect`.
 
+When defining carriers, you'll need `-XTypeOperators` to declare a `Carrier` instance over (`:+:`), `-XFlexibleInstances` to loosen the conditions on the instance, `-XMultiParamTypeClasses` since `Carrier` takes two parameters, and `-XUndecidableInstances` to satisfy the coverage condition for this instance.
+
 [common]: https://github.com/fused-effects/fused-effects/blob/master/docs/common_errors.md
 
-The following invocation, taken from the teletype example, should suffice for any use or construction of effects:
+The following invocation, taken from the teletype example, should suffice for most use or construction of effects and carriers:
 
 ```haskell
-{-# LANGUAGE DeriveFunctor, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving,
-    KindSignatures, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
+{-# LANGUAGE DeriveFunctor, DeriveGeneric, DerivingStrategies, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
 ```
 
 ### Defining new effects
diff --git a/benchmark/Bench.hs b/benchmark/Bench.hs
--- a/benchmark/Bench.hs
+++ b/benchmark/Bench.hs
@@ -1,14 +1,15 @@
 {-# LANGUAGE DeriveFunctor, FlexibleContexts, FlexibleInstances, LambdaCase, MultiParamTypeClasses, RankNTypes, TypeApplications, TypeOperators, UndecidableInstances #-}
-module Main where
+module Main
+( main
+) where
 
-import Control.Effect
 import Control.Effect.Carrier
 import Control.Effect.Interpret
-import Control.Effect.Pure
 import Control.Effect.Writer
 import Control.Effect.State
 import Control.Monad (ap, replicateM_)
 import Criterion.Main
+import Data.Functor.Identity
 import Data.Monoid (Sum(..))
 
 main :: IO ()
@@ -59,10 +60,10 @@
     ]
   ]
 
-tellLoop :: (Applicative m, Carrier sig m, Member (Writer (Sum Int)) sig) => Int -> m ()
+tellLoop :: (Carrier sig m, Member (Writer (Sum Int)) sig) => Int -> m ()
 tellLoop i = replicateM_ i (tell (Sum (1 :: Int)))
 
-modLoop :: (Applicative m, Carrier sig m, Member (State (Sum Int)) sig) => Int -> m ()
+modLoop :: (Carrier sig m, Member (State (Sum Int)) sig) => Int -> m ()
 modLoop i = replicateM_ i (modify (+ (Sum (1 :: Int))))
 
 newtype Cod m a = Cod { unCod :: forall b . (a -> m b) -> m b }
@@ -78,5 +79,5 @@
 instance Monad (Cod m) where
   Cod a >>= f = Cod (\ k -> a (runCod k . f))
 
-instance Carrier sig m => Carrier sig (Cod m) where
-  eff op = Cod (\ k -> eff (hmap (runCod pure) (fmap' (runCod k) op)))
+instance (Carrier sig m, Effect sig) => Carrier sig (Cod m) where
+  eff op = Cod (\ k -> eff (handle (Identity ()) (runCod (pure . Identity) . runIdentity) op) >>= k . runIdentity)
diff --git a/examples/Main.hs b/examples/Main.hs
--- a/examples/Main.hs
+++ b/examples/Main.hs
@@ -1,4 +1,6 @@
-module Main where
+module Main
+( main
+) where
 
 import qualified Parser
 import qualified ReinterpretLog
diff --git a/examples/Parser.hs b/examples/Parser.hs
--- a/examples/Parser.hs
+++ b/examples/Parser.hs
@@ -1,18 +1,16 @@
-{-# LANGUAGE DeriveFoldable, DeriveFunctor, DeriveTraversable, ExistentialQuantification, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, KindSignatures, MultiParamTypeClasses, StandaloneDeriving, TypeOperators, UndecidableInstances #-}
+{-# LANGUAGE DeriveAnyClass, DeriveGeneric, DeriveTraversable, DerivingStrategies, ExistentialQuantification, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, StandaloneDeriving, TypeOperators, UndecidableInstances #-}
 module Parser
 ( spec
 ) where
 
-import Control.Effect
 import Control.Effect.Carrier
 import Control.Effect.Cut
 import Control.Effect.NonDet
 import Control.Effect.State
-import Control.Effect.Sum
 import Control.Monad (replicateM)
 import Data.Char
-import Data.Coerce
 import Data.List (intercalate)
+import GHC.Generics (Generic1)
 import Test.Hspec
 import Test.Hspec.QuickCheck
 import Test.QuickCheck
@@ -74,15 +72,9 @@
             replicateM m (vector n')
 
 
-data Symbol (m :: * -> *) k = Satisfy (Char -> Bool) (Char -> k)
-  deriving (Functor)
-
-instance HFunctor Symbol where
-  hmap _ = coerce
-  {-# INLINE hmap #-}
-
-instance Effect Symbol where
-  handle state handler = coerce . fmap (handler . (<$ state))
+data Symbol m k = Satisfy (Char -> Bool) (Char -> m k)
+  deriving stock (Functor, Generic1)
+  deriving anyclass (HFunctor, Effect)
 
 satisfy :: (Carrier sig m, Member Symbol sig) => (Char -> Bool) -> m Char
 satisfy p = send (Satisfy p pure)
@@ -103,7 +95,7 @@
         exhaustive _       = empty
 
 newtype ParseC m a = ParseC { runParseC :: StateC String m a }
-  deriving (Alternative, Applicative, Functor, Monad)
+  deriving newtype (Alternative, Applicative, Functor, Monad)
 
 instance (Alternative m, Carrier sig m, Effect sig) => Carrier (Symbol :+: sig) (ParseC m) where
   eff (L (Satisfy p k)) = do
diff --git a/examples/ReinterpretLog.hs b/examples/ReinterpretLog.hs
--- a/examples/ReinterpretLog.hs
+++ b/examples/ReinterpretLog.hs
@@ -10,7 +10,9 @@
 --   structured log messages as strings.
 
 
+{-# LANGUAGE DeriveAnyClass             #-}
 {-# LANGUAGE DeriveFunctor              #-}
+{-# LANGUAGE DeriveGeneric              #-}
 {-# LANGUAGE DerivingStrategies         #-}
 {-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE FlexibleInstances          #-}
@@ -27,17 +29,18 @@
 
 module ReinterpretLog
   ( spec
+  , application
+  , runApplication
   ) where
 
-import Control.Effect
 import Control.Effect.Carrier
+import Control.Effect.Lift
 import Control.Effect.Reader
-import Control.Effect.Sum
 import Control.Effect.Writer
 import Control.Monad.IO.Class (MonadIO(..))
-import Data.Coerce            (coerce)
 import Data.Function          ((&))
 import Data.Kind              (Type)
+import GHC.Generics           (Generic1)
 import Prelude                hiding (log)
 import Test.Hspec
 
@@ -105,25 +108,9 @@
 
 -- Log an 'a', then continue with 'k'.
 data Log (a :: Type) (m :: Type -> Type) (k :: Type)
-  = Log a k
-  deriving stock (Functor)
-
--- Log is a "first order" effect, so the Effect and HFunctor instance are
--- boilerplate. See https://github.com/fused-effects/fused-effects/issues/54
-instance Effect (Log a) where
-  handle ::
-       Functor f
-    => f ()
-    -> (forall x. f (m x) -> n (f x))
-    -> Log a m (m b)
-    -> Log a n (n (f b))
-  handle state handler =
-    coerce . fmap (handler . ((<$ state)))
-
-instance HFunctor (Log a) where
-  hmap :: (forall x. m x -> n x) -> Log a m k -> Log a n k
-  hmap _ =
-    coerce
+  = Log a (m k)
+  deriving stock (Functor, Generic1)
+  deriving anyclass (HFunctor, Effect)
 
 -- Log an 'a'.
 log ::
@@ -154,7 +141,7 @@
      -- ... the 'LogStdoutC m' monad can interpret 'Log String :+: sig' effects
   => Carrier (Log String :+: sig) (LogStdoutC m) where
 
-  eff :: (Log String :+: sig) (LogStdoutC m) (LogStdoutC m a) -> LogStdoutC m a
+  eff :: (Log String :+: sig) (LogStdoutC m) a -> LogStdoutC m a
   eff = \case
     L (Log message k) ->
       LogStdoutC $ do
@@ -162,7 +149,7 @@
         runLogStdout k
 
     R other ->
-      LogStdoutC (eff (handlePure runLogStdout other))
+      LogStdoutC (eff (hmap runLogStdout other))
 
 -- The 'LogStdoutC' runner.
 runLogStdout ::
@@ -189,7 +176,7 @@
   => Carrier (Log s :+: sig) (ReinterpretLogC s t m) where
 
   eff ::
-       (Log s :+: sig) (ReinterpretLogC s t m) (ReinterpretLogC s t m a)
+       (Log s :+: sig) (ReinterpretLogC s t m) a
     -> ReinterpretLogC s t m a
   eff = \case
     L (Log s k) ->
@@ -227,7 +214,7 @@
   => Carrier (Log s :+: sig) (CollectLogMessagesC s m) where
 
   eff ::
-       (Log s :+: sig) (CollectLogMessagesC s m) (CollectLogMessagesC s m a)
+       (Log s :+: sig) (CollectLogMessagesC s m) a
     -> CollectLogMessagesC s m a
   eff = \case
     L (Log s k) ->
diff --git a/examples/Teletype.hs b/examples/Teletype.hs
--- a/examples/Teletype.hs
+++ b/examples/Teletype.hs
@@ -1,16 +1,17 @@
-{-# LANGUAGE DeriveAnyClass, DeriveFunctor, DerivingStrategies, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, KindSignatures, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
+{-# LANGUAGE DeriveAnyClass, DeriveFunctor, DeriveGeneric, DerivingStrategies, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
 
-module Teletype where
+module Teletype
+( spec
+, runTeletypeIO
+) where
 
 import Prelude hiding (read)
 
-import Control.Effect
 import Control.Effect.Carrier
 import Control.Effect.State
-import Control.Effect.Sum
 import Control.Effect.Writer
 import Control.Monad.IO.Class
-import Data.Coerce
+import GHC.Generics (Generic1)
 import Test.Hspec
 import Test.Hspec.QuickCheck
 
@@ -25,10 +26,11 @@
   prop "writes multiple things" $
     \ input output1 output2 -> run (runTeletypeRet input (write output1 >> write output2)) `shouldBe` ([output1, output2], (input, ()))
 
-data Teletype (m :: * -> *) k
-  = Read (String -> k)
-  | Write String k
-  deriving (Functor, HFunctor, Effect)
+data Teletype m k
+  = Read (String -> m k)
+  | Write String (m k)
+  deriving stock (Functor, Generic1)
+  deriving anyclass (HFunctor, Effect)
 
 read :: (Member Teletype sig, Carrier sig m) => m String
 read = send (Read pure)
diff --git a/fused-effects.cabal b/fused-effects.cabal
--- a/fused-effects.cabal
+++ b/fused-effects.cabal
@@ -1,9 +1,11 @@
+cabal-version:       2.2
+
 name:                fused-effects
-version:             0.4.0.0
+version:             0.5.0.0
 synopsis:            A fast, flexible, fused effect system.
 description:         A fast, flexible, fused effect system, à la Effect Handlers in Scope, Monad Transformers and Modular Algebraic Effects: What Binds Them Together, and Fusion for Free—Efficient Algebraic Effect Handlers.
 homepage:            https://github.com/fused-effects/fused-effects
-license:             BSD3
+license:             BSD-3-Clause
 license-file:        LICENSE
 author:              Nicolas Wu, Tom Schrijvers, Rob Rix, Patrick Thomson
 maintainer:          robrix@github.com
@@ -13,13 +15,19 @@
 extra-source-files:
   README.md
   ChangeLog.md
-cabal-version:       >=1.10
 
 tested-with:         GHC == 8.2.2
                    , GHC == 8.4.4
                    , GHC == 8.6.2
 
+common common
+  default-language:    Haskell2010
+  ghc-options:         -Weverything -Wno-missing-local-signatures -Wno-missing-import-lists -Wno-implicit-prelude -Wno-safe -Wno-unsafe -Wno-name-shadowing -Wno-monomorphism-restriction -Wno-missed-specialisations -Wno-all-missed-specialisations
+  if (impl(ghc >= 8.6))
+    ghc-options:       -Wno-star-is-type
+
 library
+  import:              common
   exposed-modules:     Control.Effect
                      , Control.Effect.Carrier
                      , Control.Effect.Cull
@@ -50,15 +58,10 @@
                      , random
                      , transformers
   hs-source-dirs:      src
-  default-language:    Haskell2010
-  ghc-options:         -Weverything -Wno-missing-local-signatures -Wno-missing-import-lists -Wno-implicit-prelude -Wno-safe -Wno-unsafe -Wno-name-shadowing -Wno-monomorphism-restriction -Wno-missed-specialisations -Wno-all-missed-specialisations
-  if (impl(ghc >= 8.4))
-    ghc-options:       -Wno-missing-export-lists
-  if (impl(ghc >= 8.6))
-    ghc-options:       -Wno-star-is-type
 
 
 test-suite examples
+  import:              common
   type:                exitcode-stdio-1.0
   main-is:             Main.hs
   other-modules:       Parser
@@ -70,9 +73,9 @@
                      , QuickCheck >= 2.7 && < 3
                      , transformers
   hs-source-dirs:      examples
-  default-language:    Haskell2010
 
 test-suite test
+  import:              common
   type:                exitcode-stdio-1.0
   main-is:             Spec.hs
   other-modules:       Control.Effect.Spec
@@ -82,26 +85,25 @@
                      , hspec >=2.4.1
                      , inspection-testing >= 0.4 && <1
   hs-source-dirs:      test
-  default-language:    Haskell2010
 
 test-suite doctest
+  import:              common
   type:                exitcode-stdio-1.0
   main-is:             Doctest.hs
   build-depends:       base >=4.9 && <4.13
                      , doctest >=0.7 && <1.0
                      , fused-effects
   hs-source-dirs:      test
-  default-language:    Haskell2010
 
 
 benchmark benchmark
+  import:             common
   type:               exitcode-stdio-1.0
   main-is:            Bench.hs
   build-depends:      base >=4.9 && <4.13
                     , criterion
                     , fused-effects
   hs-source-dirs:     benchmark
-  default-language:   Haskell2010
   ghc-options:        -threaded -rtsopts "-with-rtsopts=-N -A4m -n2m"
 
 
diff --git a/src/Control/Effect.hs b/src/Control/Effect.hs
--- a/src/Control/Effect.hs
+++ b/src/Control/Effect.hs
@@ -2,7 +2,7 @@
 ( module X
 ) where
 
-import Control.Effect.Carrier   as X (Carrier, Effect)
+import Control.Effect.Carrier   as X ((:+:), Carrier, Effect, Member)
 import Control.Effect.Cull      as X (Cull, CullC, OnceC)
 import Control.Effect.Cut       as X (Cut, CutC)
 import Control.Effect.Error     as X (Error, ErrorC)
@@ -16,6 +16,5 @@
 import Control.Effect.Resource  as X (Resource, ResourceC)
 import Control.Effect.Resumable as X (Resumable, ResumableC, ResumableWithC)
 import Control.Effect.State     as X (State, StateC)
-import Control.Effect.Sum       as X ((:+:), Member, send)
 import Control.Effect.Trace     as X (Trace, TraceByPrintingC, TraceByIgnoringC, TraceByReturningC)
 import Control.Effect.Writer    as X (Writer, WriterC)
diff --git a/src/Control/Effect/Carrier.hs b/src/Control/Effect/Carrier.hs
--- a/src/Control/Effect/Carrier.hs
+++ b/src/Control/Effect/Carrier.hs
@@ -1,79 +1,197 @@
-{-# LANGUAGE DefaultSignatures, DeriveFunctor, FlexibleInstances, FunctionalDependencies, RankNTypes, UndecidableInstances #-}
+{-# LANGUAGE DefaultSignatures, DeriveFunctor, EmptyCase, FlexibleContexts, FlexibleInstances, FunctionalDependencies, RankNTypes, TypeOperators, UndecidableInstances #-}
 module Control.Effect.Carrier
 ( HFunctor(..)
 , Effect(..)
 , Carrier(..)
+, send
 , handlePure
 , handleCoercible
+-- * Generic deriving of 'HFunctor' & 'Effect' instances.
+, GHFunctor(..)
+, GEffect(..)
+-- * Re-exports
+, Pure.run
+, (Sum.:+:)(..)
+, Sum.Member(..)
 ) where
 
-import Data.Coerce
+import qualified Control.Effect.Pure as Pure
+import qualified Control.Effect.Sum as Sum
+import           Data.Coerce
+import           GHC.Generics
 
+-- | Higher-order functors of kind @(* -> *) -> (* -> *)@ map functors to functors.
+--
+--   All effects must be 'HFunctor's.
 class HFunctor h where
-  -- | Functor map. This is required to be 'fmap'.
-  --
-  --   This can go away once we have quantified constraints.
-  fmap' :: (a -> b) -> (h m a -> h m b)
-  default fmap' :: Functor (h m) => (a -> b) -> (h m a -> h m b)
+  -- | Apply a handler specified as a natural transformation to both higher-order and continuation positions within an 'HFunctor'.
+  fmap' :: Functor (h f) => (a -> b) -> h f a -> h f b
   fmap' = fmap
   {-# INLINE fmap' #-}
 
   -- | Higher-order functor map of a natural transformation over higher-order positions within the effect.
-  -- A definition for 'hmap' over first-order effects can be derived automatically.
-  hmap :: (forall x . m x -> n x) -> (h m a -> h n a)
-
-  default hmap :: Coercible (h m a) (h n a)
-               => (forall x . m x -> n x)
-               -> (h m a -> h n a)
-  hmap _ = coerce
+  --
+  -- A definition for 'hmap' over first-order effects can be derived automatically provided a 'Generic1' instance is available.
+  hmap :: Functor m => (forall x . m x -> n x) -> (h m a -> h n a)
+  default hmap :: (Functor m, Generic1 (h m), Generic1 (h n), GHFunctor m n (Rep1 (h m)) (Rep1 (h n))) => (forall x . m x -> n x) -> (h m a -> h n a)
+  hmap f = to1 . ghmap f . from1
   {-# INLINE hmap #-}
 
+{-# DEPRECATED fmap' "fmap' has been subsumed by fmap." #-}
 
+instance HFunctor Pure.Pure
+instance (HFunctor f, HFunctor g) => HFunctor (f Sum.:+: g)
+
+
 -- | The class of effect types, which must:
 --
 --   1. Be functorial in their last two arguments, and
 --   2. Support threading effects in higher-order positions through using the carrier’s suspended state.
 --
--- All first-order effects (those without recursive occurrences of @m@) admit a default definition
--- of 'handle'. The @-XDeriveAnyClass@ extension allows derivation of both 'HFunctor' and 'Effect':
---
--- @
---   data State s (m :: * -> *) k
---     = Get (s -> k)
---     | Put s k
---       deriving (Functor, HFunctor, Effect)
--- @
+-- All first-order effects (those without existential occurrences of @m@) admit a default definition of 'handle' provided a 'Generic1' instance is available for the effect.
 class HFunctor sig => Effect sig where
   -- | Handle any effects in a signature by threading the carrier’s state all the way through to the continuation.
-  handle :: Functor f
+  handle :: (Functor f, Monad m)
          => f ()
          -> (forall x . f (m x) -> n (f x))
-         -> sig m (m a)
-         -> sig n (n (f a))
-
-  default handle :: (Functor f, Coercible (sig m (n (f a))) (sig n (n (f a))))
+         -> sig m a
+         -> sig n (f a)
+  default handle :: (Functor f, Monad m, Generic1 (sig m), Generic1 (sig n), GEffect m n (Rep1 (sig m)) (Rep1 (sig n)))
                  => f ()
                  -> (forall x . f (m x) -> n (f x))
-                 -> sig m (m a)
-                 -> sig n (n (f a))
-  handle state handler = coerce . fmap' (handler . (<$ state))
+                 -> sig m a
+                 -> sig n (f a)
+  handle state handler = to1 . ghandle state handler . from1
   {-# INLINE handle #-}
 
+instance Effect Pure.Pure
+instance (Effect f, Effect g) => Effect (f Sum.:+: g)
 
 
 -- | The class of carriers (results) for algebras (effect handlers) over signatures (effects), whose actions are given by the 'eff' method.
 class (HFunctor sig, Monad m) => Carrier sig m | m -> sig where
   -- | Construct a value in the carrier for an effect signature (typically a sum of a handled effect and any remaining effects).
-  eff :: sig m (m a) -> m a
+  eff :: sig m a -> m a
 
+
+instance Carrier Pure.Pure Pure.PureC where
+  eff v = case v of {}
+  {-# INLINE eff #-}
+
+
+-- | Construct a request for an effect to be interpreted by some handler later on.
+send :: (Sum.Member effect sig, Carrier sig m) => effect m a -> m a
+send = eff . Sum.inj
+{-# INLINE send #-}
+
+
 -- | Apply a handler specified as a natural transformation to both higher-order and continuation positions within an 'HFunctor'.
-handlePure :: HFunctor sig => (forall x . f x -> g x) -> sig f (f a) -> sig g (g a)
-handlePure handler = hmap handler . fmap' handler
+handlePure :: (HFunctor sig, Functor f) => (forall x . f x -> g x) -> sig f a -> sig g a
+handlePure = hmap
 {-# INLINE handlePure #-}
+{-# DEPRECATED handlePure "handlePure has been subsumed by hmap." #-}
 
 -- | Thread a 'Coercible' carrier through an 'HFunctor'.
 --
 --   This is applicable whenever @f@ is 'Coercible' to @g@, e.g. simple @newtype@s.
-handleCoercible :: (HFunctor sig, Coercible f g) => sig f (f a) -> sig g (g a)
-handleCoercible = handlePure coerce
+handleCoercible :: (HFunctor sig, Functor f, Coercible f g) => sig f a -> sig g a
+handleCoercible = hmap coerce
 {-# INLINE handleCoercible #-}
+
+
+-- | Generic implementation of 'HFunctor'.
+class GHFunctor m m' rep rep' where
+  -- | Generic implementation of 'hmap'.
+  ghmap :: Functor m => (forall x . m x -> m' x) -> (rep a -> rep' a)
+
+instance GHFunctor m m' rep rep' => GHFunctor m m' (M1 i c rep) (M1 i c rep') where
+  ghmap f = M1 . ghmap f . unM1
+  {-# INLINE ghmap #-}
+
+instance (GHFunctor m m' l l', GHFunctor m m' r r') => GHFunctor m m' (l :+: r) (l' :+: r') where
+  ghmap f (L1 l) = L1 (ghmap f l)
+  ghmap f (R1 r) = R1 (ghmap f r)
+  {-# INLINE ghmap #-}
+
+instance (GHFunctor m m' l l', GHFunctor m m' r r') => GHFunctor m m' (l :*: r) (l' :*: r') where
+  ghmap f (l :*: r) = ghmap f l :*: ghmap f r
+  {-# INLINE ghmap #-}
+
+instance GHFunctor m m' V1 V1 where
+  ghmap _ v = case v of {}
+  {-# INLINE ghmap #-}
+
+instance GHFunctor m m' U1 U1 where
+  ghmap _ = id
+  {-# INLINE ghmap #-}
+
+instance GHFunctor m m' (K1 R c) (K1 R c) where
+  ghmap _ = coerce
+  {-# INLINE ghmap #-}
+
+instance GHFunctor m m' Par1 Par1 where
+  ghmap _ = coerce
+  {-# INLINE ghmap #-}
+
+instance (Functor f, GHFunctor m m' g g') => GHFunctor m m' (f :.: g) (f :.: g') where
+  ghmap f = Comp1 . fmap (ghmap f) . unComp1
+  {-# INLINE ghmap #-}
+
+instance GHFunctor m m' (Rec1 m) (Rec1 m') where
+  ghmap f = Rec1 . f . unRec1
+  {-# INLINE ghmap #-}
+
+instance HFunctor f => GHFunctor m m' (Rec1 (f m)) (Rec1 (f m')) where
+  ghmap f = Rec1 . hmap f . unRec1
+  {-# INLINE ghmap #-}
+
+
+-- | Generic implementation of 'Effect'.
+class GEffect m m' rep rep' where
+  -- | Generic implementation of 'handle'.
+  ghandle :: (Functor f, Monad m)
+          => f ()
+          -> (forall x . f (m x) -> m' (f x))
+          -> rep a
+          -> rep' (f a)
+
+instance GEffect m m' rep rep' => GEffect m m' (M1 i c rep) (M1 i c rep') where
+  ghandle state handler = M1 . ghandle state handler . unM1
+  {-# INLINE ghandle #-}
+
+instance (GEffect m m' l l', GEffect m m' r r') => GEffect m m' (l :+: r) (l' :+: r') where
+  ghandle state handler (L1 l) = L1 (ghandle state handler l)
+  ghandle state handler (R1 r) = R1 (ghandle state handler r)
+  {-# INLINE ghandle #-}
+
+instance (GEffect m m' l l', GEffect m m' r r') => GEffect m m' (l :*: r) (l' :*: r') where
+  ghandle state handler (l :*: r) = ghandle state handler l :*: ghandle state handler r
+  {-# INLINE ghandle #-}
+
+instance GEffect m m' V1 V1 where
+  ghandle _ _ v = case v of {}
+  {-# INLINE ghandle #-}
+
+instance GEffect m m' U1 U1 where
+  ghandle _ _ = coerce
+  {-# INLINE ghandle #-}
+
+instance GEffect m m' (K1 R c) (K1 R c) where
+  ghandle _ _ = coerce
+  {-# INLINE ghandle #-}
+
+instance GEffect m m' Par1 Par1 where
+  ghandle state _ = Par1 . (<$ state) . unPar1
+  {-# INLINE ghandle #-}
+
+instance (Functor f, GEffect m m' g g') => GEffect m m' (f :.: g) (f :.: g') where
+  ghandle state handler = Comp1 . fmap (ghandle state handler) . unComp1
+  {-# INLINE ghandle #-}
+
+instance GEffect m m' (Rec1 m) (Rec1 m') where
+  ghandle state handler = Rec1 . handler . (<$ state) . unRec1
+  {-# INLINE ghandle #-}
+
+instance Effect f => GEffect m m' (Rec1 (f m)) (Rec1 (f m')) where
+  ghandle state handler = Rec1 . handle state handler . unRec1
+  {-# INLINE ghandle #-}
diff --git a/src/Control/Effect/Cull.hs b/src/Control/Effect/Cull.hs
--- a/src/Control/Effect/Cull.hs
+++ b/src/Control/Effect/Cull.hs
@@ -1,32 +1,38 @@
 {-# LANGUAGE DeriveFunctor, ExistentialQuantification, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, LambdaCase, MultiParamTypeClasses, StandaloneDeriving, TypeOperators, UndecidableInstances #-}
 module Control.Effect.Cull
-( Cull(..)
+( -- * Cull effect
+  Cull(..)
 , cull
+  -- * Cull carriers
 , runCull
 , CullC(..)
 , runNonDetOnce
 , OnceC(..)
+-- * Re-exports
+, Carrier
+, Member
+, run
 ) where
 
 import Control.Applicative (Alternative(..))
 import Control.Effect.Carrier
 import Control.Effect.NonDet
 import Control.Effect.Reader
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 import Prelude hiding (fail)
 
 -- | 'Cull' effects are used with 'NonDet' to provide control over branching.
 data Cull m k
-  = forall a . Cull (m a) (a -> k)
+  = forall a . Cull (m a) (a -> m k)
 
-deriving instance Functor (Cull m)
+deriving instance Functor m => Functor (Cull m)
 
 instance HFunctor Cull where
-  hmap f (Cull m k) = Cull (f m) k
+  hmap f (Cull m k) = Cull (f m) (f . k)
   {-# INLINE hmap #-}
 
 instance Effect Cull where
@@ -35,21 +41,21 @@
 
 -- | Cull nondeterminism in the argument, returning at most one result.
 --
---   prop> run (runNonDet (runCull (cull (pure a <|> pure b)))) == [a]
---   prop> run (runNonDet (runCull (cull (pure a <|> pure b) <|> pure c))) == [a, c]
---   prop> run (runNonDet (runCull (cull (asum (map pure (repeat a)))))) == [a]
+--   prop> run (runNonDet (runCull (cull (pure a <|> pure b)))) === [a]
+--   prop> run (runNonDet (runCull (cull (pure a <|> pure b) <|> pure c))) === [a, c]
+--   prop> run (runNonDet (runCull (cull (asum (map pure (repeat a)))))) === [a]
 cull :: (Carrier sig m, Member Cull sig) => m a -> m a
 cull m = send (Cull m pure)
 
 
 -- | Run a 'Cull' effect. Branches outside of any 'cull' block will not be pruned.
 --
---   prop> run (runNonDet (runCull (pure a <|> pure b))) == [a, b]
+--   prop> run (runNonDet (runCull (pure a <|> pure b))) === [a, b]
 runCull :: Alternative m => CullC m a -> m a
 runCull (CullC m) = runNonDetC (runReader False m) ((<|>) . pure) empty
 
 newtype CullC m a = CullC { runCullC :: ReaderC Bool (NonDetC m) a }
-  deriving (Applicative, Functor, Monad, MonadFail, MonadIO)
+  deriving (Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO)
 
 instance Alternative (CullC m) where
   empty = CullC empty
@@ -78,13 +84,13 @@
 --
 --   Unlike 'runNonDet', this will terminate immediately upon finding a solution.
 --
---   prop> run (runNonDetOnce (asum (map pure (repeat a)))) == [a]
---   prop> run (runNonDetOnce (asum (map pure (repeat a)))) == Just a
+--   prop> run (runNonDetOnce (asum (map pure (repeat a)))) === [a]
+--   prop> run (runNonDetOnce (asum (map pure (repeat a)))) === Just a
 runNonDetOnce :: (Alternative f, Carrier sig m, Effect sig) => OnceC m a -> m (f a)
 runNonDetOnce = runNonDet . runCull . cull . runOnceC
 
 newtype OnceC m a = OnceC { runOnceC :: CullC (NonDetC m) a }
-  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus)
+  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus)
 
 instance (Carrier sig m, Effect sig) => Carrier (NonDet :+: sig) (OnceC m) where
   eff = OnceC . eff . R . R . handleCoercible
diff --git a/src/Control/Effect/Cut.hs b/src/Control/Effect/Cut.hs
--- a/src/Control/Effect/Cut.hs
+++ b/src/Control/Effect/Cut.hs
@@ -1,20 +1,26 @@
 {-# LANGUAGE DeriveFunctor, ExistentialQuantification, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, LambdaCase, MultiParamTypeClasses, RankNTypes, StandaloneDeriving, TypeOperators, UndecidableInstances #-}
 module Control.Effect.Cut
-( Cut(..)
+( -- * Cut effect
+  Cut(..)
 , cutfail
 , call
 , cut
+  -- * Cut carrier
 , runCut
 , runCutAll
 , CutC(..)
+-- * Re-exports
+, Carrier
+, Member
+, run
 ) where
 
 import Control.Applicative (Alternative(..))
 import Control.Effect.Carrier
 import Control.Effect.NonDet
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 import Prelude hiding (fail)
@@ -22,13 +28,13 @@
 -- | 'Cut' effects are used with 'NonDet' to provide control over backtracking.
 data Cut m k
   = Cutfail
-  | forall a . Call (m a) (a -> k)
+  | forall a . Call (m a) (a -> m k)
 
-deriving instance Functor (Cut m)
+deriving instance Functor m => Functor (Cut m)
 
 instance HFunctor Cut where
   hmap _ Cutfail    = Cutfail
-  hmap f (Call m k) = Call (f m) k
+  hmap f (Call m k) = Call (f m) (f . k)
   {-# INLINE hmap #-}
 
 instance Effect Cut where
@@ -40,24 +46,24 @@
 --
 --   Contrast with 'empty', which fails the current branch but allows backtracking.
 --
---   prop> run (runNonDet (runCut (cutfail <|> pure a))) == []
---   prop> run (runNonDet (runCut (pure a <|> cutfail))) == [a]
+--   prop> run (runNonDet (runCut (cutfail <|> pure a))) === []
+--   prop> run (runNonDet (runCut (pure a <|> cutfail))) === [a]
 cutfail :: (Carrier sig m, Member Cut sig) => m a
 cutfail = send Cutfail
 {-# INLINE cutfail #-}
 
 -- | Delimit the effect of 'cutfail's, allowing backtracking to resume.
 --
---   prop> run (runNonDet (runCut (call (cutfail <|> pure a) <|> pure b))) == [b]
+--   prop> run (runNonDet (runCut (call (cutfail <|> pure a) <|> pure b))) === [b]
 call :: (Carrier sig m, Member Cut sig) => m a -> m a
 call m = send (Call m pure)
 {-# INLINE call #-}
 
 -- | Commit to the current branch, preventing backtracking within the nearest enclosing 'call' (if any) on failure.
 --
---   prop> run (runNonDet (runCut (pure a <|> cut *> pure b))) == [a, b]
---   prop> run (runNonDet (runCut (cut *> pure a <|> pure b))) == [a]
---   prop> run (runNonDet (runCut (cut *> empty <|> pure a))) == []
+--   prop> run (runNonDet (runCut (pure a <|> cut *> pure b))) === [a, b]
+--   prop> run (runNonDet (runCut (cut *> pure a <|> pure b))) === [a]
+--   prop> run (runNonDet (runCut (cut *> empty <|> pure a))) === []
 cut :: (Alternative m, Carrier sig m, Member Cut sig) => m ()
 cut = pure () <|> cutfail
 {-# INLINE cut #-}
@@ -65,7 +71,7 @@
 
 -- | Run a 'Cut' effect within an underlying 'Alternative' instance (typically another 'Carrier' for a 'NonDet' effect).
 --
---   prop> run (runNonDetOnce (runCut (pure a))) == Just a
+--   prop> run (runNonDetOnce (runCut (pure a))) === Just a
 runCut :: Alternative m => CutC m a -> m a
 runCut m = runCutC m ((<|>) . pure) empty empty
 
@@ -100,6 +106,10 @@
 instance MonadFail m => MonadFail (CutC m) where
   fail s = CutC (\ _ _ _ -> fail s)
   {-# INLINE fail #-}
+
+instance MonadFix m => MonadFix (CutC m) where
+  mfix f = CutC (\ cons nil _ -> mfix (\ a -> runCutC (f (head a)) (fmap . (:)) (pure []) (pure [])) >>= foldr cons nil)
+  {-# INLINE mfix #-}
 
 instance MonadIO m => MonadIO (CutC m) where
   liftIO io = CutC (\ cons nil _ -> liftIO io >>= flip cons nil)
diff --git a/src/Control/Effect/Error.hs b/src/Control/Effect/Error.hs
--- a/src/Control/Effect/Error.hs
+++ b/src/Control/Effect/Error.hs
@@ -1,30 +1,36 @@
 {-# LANGUAGE DeriveFunctor, ExistentialQuantification, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, StandaloneDeriving, TypeOperators, UndecidableInstances #-}
 module Control.Effect.Error
-( Error(..)
+( -- * Error effect
+  Error(..)
 , throwError
 , catchError
+  -- * Error carrier
 , runError
 , ErrorC(..)
+  -- * Re-exports
+, Carrier
+, Member
+, run
 ) where
 
 import Control.Applicative (Alternative(..), liftA2)
 import Control.Effect.Carrier
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..), (<=<))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 import Prelude hiding (fail)
 
 data Error exc m k
   = Throw exc
-  | forall b . Catch (m b) (exc -> m b) (b -> k)
+  | forall b . Catch (m b) (exc -> m b) (b -> m k)
 
-deriving instance Functor (Error exc m)
+deriving instance Functor m => Functor (Error exc m)
 
 instance HFunctor (Error exc) where
   hmap _ (Throw exc)   = Throw exc
-  hmap f (Catch m h k) = Catch (f m) (f . h) k
+  hmap f (Catch m h k) = Catch (f m) (f . h) (f . k)
 
 instance Effect (Error exc) where
   handle _     _       (Throw exc)   = Throw exc
@@ -32,7 +38,7 @@
 
 -- | Throw an error, escaping the current computation up to the nearest 'catchError' (if any).
 --
---   prop> run (runError (throwError a)) == Left @Int @Int a
+--   prop> run (runError (throwError a)) === Left @Int @Int a
 throwError :: (Member (Error exc) sig, Carrier sig m) => exc -> m a
 throwError = send . Throw
 
@@ -44,16 +50,16 @@
 -- consider if 'Control.Effect.Resource' fits your use case; if not, use 'liftIO' with
 -- 'Control.Exception.try' or use 'Control.Exception.Catch' from outside the effect invocation.
 --
---   prop> run (runError (pure a `catchError` pure)) == Right a
---   prop> run (runError (throwError a `catchError` pure)) == Right @Int @Int a
---   prop> run (runError (throwError a `catchError` (throwError @Int))) == Left @Int @Int a
+--   prop> run (runError (pure a `catchError` pure)) === Right a
+--   prop> run (runError (throwError a `catchError` pure)) === Right @Int @Int a
+--   prop> run (runError (throwError a `catchError` (throwError @Int))) === Left @Int @Int a
 catchError :: (Member (Error exc) sig, Carrier sig m) => m a -> (exc -> m a) -> m a
 catchError m h = send (Catch m h pure)
 
 
 -- | Run an 'Error' effect, returning uncaught errors in 'Left' and successful computations’ values in 'Right'.
 --
---   prop> run (runError (pure a)) == Right @Int @Int a
+--   prop> run (runError (pure a)) === Right @Int @Int a
 runError :: ErrorC exc m a -> m (Either exc a)
 runError = runErrorC
 
@@ -75,6 +81,10 @@
 instance Monad m => Monad (ErrorC e m) where
   ErrorC a >>= f = ErrorC (a >>= either (pure . Left) (runError . f))
   {-# INLINE (>>=) #-}
+
+instance MonadFix m => MonadFix (ErrorC e m) where
+  mfix f = ErrorC (mfix (runError . either (error "mfix (ErrorC): function returned failure") f))
+  {-# INLINE mfix #-}
 
 instance MonadIO m => MonadIO (ErrorC e m) where
   liftIO io = ErrorC (Right <$> liftIO io)
diff --git a/src/Control/Effect/Fail.hs b/src/Control/Effect/Fail.hs
--- a/src/Control/Effect/Fail.hs
+++ b/src/Control/Effect/Fail.hs
@@ -1,33 +1,40 @@
-{-# LANGUAGE DeriveAnyClass, DeriveFunctor, DerivingStrategies, FlexibleInstances, GeneralizedNewtypeDeriving, KindSignatures, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
+{-# LANGUAGE DeriveAnyClass, DeriveFunctor, DeriveGeneric, DerivingStrategies, FlexibleInstances, GeneralizedNewtypeDeriving, KindSignatures, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
 module Control.Effect.Fail
-( Fail(..)
-, MonadFail(..)
+( -- * Fail effect
+  Fail(..)
+  -- * Fail carrier
 , runFail
 , FailC(..)
+  -- * Re-exports
+, Carrier
+, Member
+, MonadFail(..)
+, run
 ) where
 
 import Control.Applicative (Alternative(..))
 import Control.Effect.Carrier
 import Control.Effect.Error
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
+import GHC.Generics (Generic1)
 import Prelude hiding (fail)
 
 newtype Fail (m :: * -> *) k = Fail String
-  deriving stock Functor
+  deriving stock (Functor, Generic1)
   deriving anyclass (HFunctor, Effect)
 
 -- | Run a 'Fail' effect, returning failure messages in 'Left' and successful computations’ results in 'Right'.
 --
---   prop> run (runFail (pure a)) == Right a
+--   prop> run (runFail (pure a)) === Right a
 runFail :: FailC m a -> m (Either String a)
 runFail = runError . runFailC
 
 newtype FailC m a = FailC { runFailC :: ErrorC String m a }
-  deriving newtype (Alternative, Applicative, Functor, Monad, MonadIO, MonadPlus, MonadTrans)
+  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFix, MonadIO, MonadPlus, MonadTrans)
 
 instance (Carrier sig m, Effect sig) => MonadFail (FailC m) where
   fail s = FailC (throwError s)
diff --git a/src/Control/Effect/Fresh.hs b/src/Control/Effect/Fresh.hs
--- a/src/Control/Effect/Fresh.hs
+++ b/src/Control/Effect/Fresh.hs
@@ -1,30 +1,36 @@
 {-# LANGUAGE DeriveFunctor, ExistentialQuantification, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, StandaloneDeriving, TypeOperators, UndecidableInstances #-}
 module Control.Effect.Fresh
-( Fresh(..)
+( -- * Fresh effect
+  Fresh(..)
 , fresh
 , resetFresh
+  -- * Fresh carrier
 , runFresh
 , FreshC(..)
+  -- * Re-exports
+, Carrier
+, Member
+, run
 ) where
 
 import Control.Applicative (Alternative(..))
 import Control.Effect.Carrier
 import Control.Effect.State
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 
 data Fresh m k
-  = Fresh (Int -> k)
-  | forall b . Reset (m b) (b -> k)
+  = Fresh (Int -> m k)
+  | forall b . Reset (m b) (b -> m k)
 
-deriving instance Functor (Fresh m)
+deriving instance Functor m => Functor (Fresh m)
 
 instance HFunctor Fresh where
-  hmap _ (Fresh   k) = Fresh k
-  hmap f (Reset m k) = Reset (f m) k
+  hmap f (Fresh   k) = Fresh       (f . k)
+  hmap f (Reset m k) = Reset (f m) (f . k)
 
 instance Effect Fresh where
   handle state handler (Fresh   k) = Fresh (handler . (<$ state) . k)
@@ -32,26 +38,26 @@
 
 -- | Produce a fresh (i.e. unique) 'Int'.
 --
---   prop> run (runFresh (replicateM n fresh)) == nub (run (runFresh (replicateM n fresh)))
+--   prop> run (runFresh (replicateM n fresh)) === nub (run (runFresh (replicateM n fresh)))
 fresh :: (Member Fresh sig, Carrier sig m) => m Int
 fresh = send (Fresh pure)
 
 -- | Reset the fresh counter after running a computation.
 --
---   prop> run (runFresh (resetFresh (replicateM m fresh) *> replicateM n fresh)) == run (runFresh (replicateM n fresh))
+--   prop> run (runFresh (resetFresh (replicateM m fresh) *> replicateM n fresh)) === run (runFresh (replicateM n fresh))
 resetFresh :: (Member Fresh sig, Carrier sig m) => m a -> m a
 resetFresh m = send (Reset m pure)
 
 
 -- | Run a 'Fresh' effect counting up from 0.
 --
---   prop> run (runFresh (replicateM n fresh)) == [0..pred n]
---   prop> run (runFresh (replicateM n fresh *> pure b)) == b
+--   prop> run (runFresh (replicateM n fresh)) === [0..pred n]
+--   prop> run (runFresh (replicateM n fresh *> pure b)) === b
 runFresh :: Functor m => FreshC m a -> m a
 runFresh = evalState 0 . runFreshC
 
 newtype FreshC m a = FreshC { runFreshC :: StateC Int m a }
-  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus, MonadTrans)
+  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus, MonadTrans)
 
 instance (Carrier sig m, Effect sig) => Carrier (Fresh :+: sig) (FreshC m) where
   eff (L (Fresh   k)) = FreshC $ do
diff --git a/src/Control/Effect/Interpose.hs b/src/Control/Effect/Interpose.hs
--- a/src/Control/Effect/Interpose.hs
+++ b/src/Control/Effect/Interpose.hs
@@ -10,9 +10,13 @@
   , runInterpose
   ) where
 
+import Control.Applicative
 import Control.Effect.Carrier
 import Control.Effect.Reader
-import Control.Effect.Sum
+import Control.Monad (MonadPlus (..))
+import Control.Monad.Fail
+import Control.Monad.Fix
+import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 
 -- | 'runInterpose' takes a handler for a given effect (such as 'State' or 'Reader')
@@ -21,28 +25,28 @@
 -- the intercepted effect, and you can pass the effect on to the original handler
 -- using 'send'.
 --
---   prop> run . evalState @Int a . runInterpose @(State Int) (\op -> modify @Int (+b) *> send op) $ modify @Int (+b) == a + b + b
+--   prop> run . evalState @Int a . runInterpose @(State Int) (\op -> modify @Int (+b) *> send op) $ modify @Int (+b) === a + b + b
 --
-runInterpose :: (forall x . eff m (m x) -> m x) -> InterposeC eff m a -> m a
+runInterpose :: (forall x . eff m x -> m x) -> InterposeC eff m a -> m a
 runInterpose handler = runReader (Handler handler) . runInterposeC
 
 newtype InterposeC eff m a = InterposeC { runInterposeC :: ReaderC (Handler eff m) m a }
-  deriving (Applicative, Functor, Monad)
+  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus)
 
 instance MonadTrans (InterposeC eff) where
   lift = InterposeC . lift
 
-newtype Handler eff m = Handler (forall x . eff m (m x) -> m x)
+newtype Handler eff m = Handler (forall x . eff m x -> m x)
 
-runHandler :: HFunctor eff => Handler eff m -> eff (ReaderC (Handler eff m) m) (ReaderC (Handler eff m) m a) -> m a
-runHandler h@(Handler handler) = handler . handlePure (runReader h)
+runHandler :: (HFunctor eff, Functor m) => Handler eff m -> eff (ReaderC (Handler eff m) m) a -> m a
+runHandler h@(Handler handler) = handler . hmap (runReader h)
 
 instance (HFunctor eff, Carrier sig m, Member eff sig) => Carrier sig (InterposeC eff m) where
-  eff (op :: sig (InterposeC eff m) (InterposeC eff m a))
-    | Just (op' :: eff (InterposeC eff m) (InterposeC eff m a)) <- prj op = do
+  eff (op :: sig (InterposeC eff m) a)
+    | Just (op' :: eff (InterposeC eff m) a) <- prj op = do
       handler <- InterposeC ask
       lift (runHandler handler (handleCoercible op'))
-    | otherwise = InterposeC (ReaderC (\ handler -> eff (handlePure (runReader handler . runInterposeC) op)))
+    | otherwise = InterposeC (ReaderC (\ handler -> eff (hmap (runReader handler . runInterposeC) op)))
 
 -- $setup
 -- >>> :seti -XFlexibleContexts
diff --git a/src/Control/Effect/Interpret.hs b/src/Control/Effect/Interpret.hs
--- a/src/Control/Effect/Interpret.hs
+++ b/src/Control/Effect/Interpret.hs
@@ -10,9 +10,9 @@
 import Control.Effect.Carrier
 import Control.Effect.Reader
 import Control.Effect.State
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 
@@ -22,21 +22,21 @@
 --
 --   At time of writing, a simple passthrough use of 'runInterpret' to handle a 'State' effect is about five times slower than using 'StateC' directly.
 --
---   prop> run (runInterpret (\ op -> case op of { Get k -> k a ; Put _ k -> k }) get) == a
-runInterpret :: (forall x . eff m (m x) -> m x) -> InterpretC eff m a -> m a
+--   prop> run (runInterpret (\ op -> case op of { Get k -> k a ; Put _ k -> k }) get) === a
+runInterpret :: (forall x . eff m x -> m x) -> InterpretC eff m a -> m a
 runInterpret handler = runReader (Handler handler) . runInterpretC
 
 newtype InterpretC eff m a = InterpretC { runInterpretC :: ReaderC (Handler eff m) m a }
-  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus)
+  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus)
 
 instance MonadTrans (InterpretC eff) where
   lift = InterpretC . lift
   {-# INLINE lift #-}
 
-newtype Handler eff m = Handler (forall x . eff m (m x) -> m x)
+newtype Handler eff m = Handler (forall x . eff m x -> m x)
 
-runHandler :: HFunctor eff => Handler eff m -> eff (InterpretC eff m) (InterpretC eff m a) -> m a
-runHandler h@(Handler handler) = handler . handlePure (runReader h . runInterpretC)
+runHandler :: (HFunctor eff, Functor m) => Handler eff m -> eff (InterpretC eff m) a -> m a
+runHandler h@(Handler handler) = handler . hmap (runReader h . runInterpretC)
 
 instance (HFunctor eff, Carrier sig m) => Carrier (eff :+: sig) (InterpretC eff m) where
   eff (L op) = do
@@ -52,21 +52,21 @@
 --
 --   At time of writing, a simple use of 'runInterpretState' to handle a 'State' effect is about four times slower than using 'StateC' directly.
 --
---   prop> run (runInterpretState (\ s op -> case op of { Get k -> runState s (k s) ; Put s' k -> runState s' k }) a get) == a
-runInterpretState :: (forall x . s -> eff (StateC s m) (StateC s m x) -> m (s, x)) -> s -> InterpretStateC eff s m a -> m (s, a)
+--   prop> run (runInterpretState (\ s op -> case op of { Get k -> runState s (k s) ; Put s' k -> runState s' k }) a get) === a
+runInterpretState :: (forall x . s -> eff (StateC s m) x -> m (s, x)) -> s -> InterpretStateC eff s m a -> m (s, a)
 runInterpretState handler state = runState state . runReader (HandlerState (\ eff -> StateC (\ s -> handler s eff))) . runInterpretStateC
 
 newtype InterpretStateC eff s m a = InterpretStateC { runInterpretStateC :: ReaderC (HandlerState eff s m) (StateC s m) a }
-  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus)
+  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus)
 
 instance MonadTrans (InterpretStateC eff s) where
   lift = InterpretStateC . lift . lift
   {-# INLINE lift #-}
 
-newtype HandlerState eff s m = HandlerState (forall x . eff (StateC s m) (StateC s m x) -> StateC s m x)
+newtype HandlerState eff s m = HandlerState (forall x . eff (StateC s m) x -> StateC s m x)
 
-runHandlerState :: HFunctor eff => HandlerState eff s m -> eff (InterpretStateC eff s m) (InterpretStateC eff s m a) -> StateC s m a
-runHandlerState h@(HandlerState handler) = handler . handlePure (runReader h . runInterpretStateC)
+runHandlerState :: (HFunctor eff, Functor m) => HandlerState eff s m -> eff (InterpretStateC eff s m) a -> StateC s m a
+runHandlerState h@(HandlerState handler) = handler . hmap (runReader h . runInterpretStateC)
 
 instance (HFunctor eff, Carrier sig m, Effect sig) => Carrier (eff :+: sig) (InterpretStateC eff s m) where
   eff (L op) = do
diff --git a/src/Control/Effect/Lift.hs b/src/Control/Effect/Lift.hs
--- a/src/Control/Effect/Lift.hs
+++ b/src/Control/Effect/Lift.hs
@@ -1,22 +1,29 @@
-{-# LANGUAGE DeriveAnyClass, DeriveFunctor, DerivingStrategies, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, KindSignatures, MultiParamTypeClasses #-}
+{-# LANGUAGE DeriveAnyClass, DeriveFunctor, DeriveGeneric, DerivingStrategies, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}
 module Control.Effect.Lift
-( Lift(..)
+( -- * Lift effect
+  Lift(..)
 , sendM
+  -- * Lift carrier
 , runM
 , LiftC(..)
+  -- * Re-exports
+, Carrier
+, Member
+, run
 ) where
 
 import Control.Applicative (Alternative(..))
 import Control.Effect.Carrier
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.IO.Unlift
 import Control.Monad.Trans.Class
+import GHC.Generics
 
-newtype Lift sig (m :: * -> *) k = Lift { unLift :: sig k }
-  deriving stock Functor
+newtype Lift sig m k = Lift { unLift :: sig (m k) }
+  deriving stock (Functor, Generic1)
   deriving anyclass (HFunctor, Effect)
 
 -- | Extract a 'Lift'ed 'Monad'ic action from an effectful computation.
@@ -30,7 +37,7 @@
 sendM = send . Lift . fmap pure
 
 newtype LiftC m a = LiftC { runLiftC :: m a }
-  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus)
+  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus)
 
 instance MonadTrans LiftC where
   lift = LiftC
diff --git a/src/Control/Effect/NonDet.hs b/src/Control/Effect/NonDet.hs
--- a/src/Control/Effect/NonDet.hs
+++ b/src/Control/Effect/NonDet.hs
@@ -1,32 +1,40 @@
-{-# LANGUAGE DeriveAnyClass, DeriveFunctor, FlexibleInstances, GeneralizedNewtypeDeriving, KindSignatures, MultiParamTypeClasses, RankNTypes, TypeOperators, UndecidableInstances #-}
+{-# LANGUAGE DeriveAnyClass, DeriveFunctor, DeriveGeneric, DerivingStrategies, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, RankNTypes, TypeOperators, UndecidableInstances #-}
 module Control.Effect.NonDet
-( NonDet(..)
-, Alternative(..)
+( -- * NonDet effect
+  NonDet(..)
+  -- * NonDet carrier
 , runNonDet
 , NonDetC(..)
+  -- * Re-exports
+, Alternative(..)
+, Carrier
+, Member
+, run
 ) where
 
 import Control.Applicative (Alternative(..))
 import Control.Effect.Carrier
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
+import GHC.Generics (Generic1)
 import Prelude hiding (fail)
 
-data NonDet (m :: * -> *) k
+data NonDet m k
   = Empty
-  | Choose (Bool -> k)
-  deriving (Functor, HFunctor, Effect)
+  | Choose (Bool -> m k)
+  deriving stock (Functor, Generic1)
+  deriving anyclass (HFunctor, Effect)
 
 
 -- | Run a 'NonDet' effect, collecting all branches’ results into an 'Alternative' functor.
 --
 --   Using '[]' as the 'Alternative' functor will produce all results, while 'Maybe' will return only the first. However, unlike 'runNonDetOnce', this will still enumerate the entire search space before returning, meaning that it will diverge for infinite search spaces, even when using 'Maybe'.
 --
---   prop> run (runNonDet (pure a)) == [a]
---   prop> run (runNonDet (pure a)) == Just a
+--   prop> run (runNonDet (pure a)) === [a]
+--   prop> run (runNonDet (pure a)) === Just a
 runNonDet :: (Alternative f, Applicative m) => NonDetC m a -> m (f a)
 runNonDet (NonDetC m) = m (fmap . (<|>) . pure) (pure empty)
 
@@ -35,7 +43,7 @@
   { -- | A higher-order function receiving two parameters: a function to combine each solution with the rest of the solutions, and an action to run when no results are produced.
     runNonDetC :: forall b . (a -> m b -> m b) -> m b -> m b
   }
-  deriving (Functor)
+  deriving stock (Functor)
 
 instance Applicative (NonDetC m) where
   pure a = NonDetC (\ cons -> cons a)
@@ -58,6 +66,10 @@
 instance MonadFail m => MonadFail (NonDetC m) where
   fail s = NonDetC (\ _ _ -> fail s)
   {-# INLINE fail #-}
+
+instance MonadFix m => MonadFix (NonDetC m) where
+  mfix f = NonDetC (\ cons nil -> mfix (\ a -> runNonDetC (f (head a)) (fmap . (:)) (pure [])) >>= foldr cons nil)
+  {-# INLINE mfix #-}
 
 instance MonadIO m => MonadIO (NonDetC m) where
   liftIO io = NonDetC (\ cons nil -> liftIO io >>= flip cons nil)
diff --git a/src/Control/Effect/Pure.hs b/src/Control/Effect/Pure.hs
--- a/src/Control/Effect/Pure.hs
+++ b/src/Control/Effect/Pure.hs
@@ -1,24 +1,20 @@
-{-# LANGUAGE DeriveFunctor, EmptyCase, KindSignatures, MultiParamTypeClasses #-}
+{-# LANGUAGE DeriveFunctor, DeriveGeneric, KindSignatures #-}
 module Control.Effect.Pure
-( Pure
+( -- * Pure effect
+  Pure
+  -- * Pure carrier
 , run
 , PureC(..)
 ) where
 
 import Control.Applicative
-import Control.Effect.Carrier
+import Control.Monad.Fix
 import Data.Coerce
+import Data.Function (fix)
+import GHC.Generics (Generic1)
 
 data Pure (m :: * -> *) k
-  deriving (Functor)
-
-instance HFunctor Pure where
-  hmap _ v = case v of {}
-  {-# INLINE hmap #-}
-
-instance Effect Pure where
-  handle _ _ v = case v of {}
-  {-# INLINE handle #-}
+  deriving (Functor, Generic1)
 
 
 -- | Run an action exhausted of effects to produce its final result value.
@@ -58,6 +54,6 @@
   PureC a >>= f = f a
   {-# INLINE (>>=) #-}
 
-instance Carrier Pure PureC where
-  eff v = case v of {}
-  {-# INLINE eff #-}
+instance MonadFix PureC where
+  mfix f = PureC (fix (runPureC . f))
+  {-# INLINE mfix #-}
diff --git a/src/Control/Effect/Random.hs b/src/Control/Effect/Random.hs
--- a/src/Control/Effect/Random.hs
+++ b/src/Control/Effect/Random.hs
@@ -1,60 +1,66 @@
 {-# LANGUAGE DeriveFunctor, ExistentialQuantification, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, ScopedTypeVariables, StandaloneDeriving, TypeOperators, UndecidableInstances #-}
 module Control.Effect.Random
-( Random(..)
+( -- * Random effect
+  Random(..)
+  -- * Random carrier
 , runRandom
 , evalRandom
 , execRandom
 , evalRandomIO
 , RandomC(..)
+  -- * Re-exports
+, Carrier
+, Member
 , MonadRandom(..)
 , MonadInterleave(..)
+, run
 ) where
 
 import Control.Applicative (Alternative(..))
 import Control.Effect.Carrier
 import Control.Effect.State
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.Random.Class (MonadInterleave(..), MonadRandom(..))
 import Control.Monad.IO.Class (MonadIO(..))
 import Control.Monad.Trans.Class
 import qualified System.Random as R (Random(..), RandomGen(..), StdGen, newStdGen)
 
 data Random m k
-  = forall a . R.Random a => Random (a -> k)
-  | forall a . R.Random a => RandomR (a, a) (a -> k)
-  | forall a . Interleave (m a) (a -> k)
+  = forall a . R.Random a => Random (a -> m k)
+  | forall a . R.Random a => RandomR (a, a) (a -> m k)
+  | forall a . Interleave (m a) (a -> m k)
 
-deriving instance Functor (Random m)
+deriving instance Functor m => Functor (Random m)
 
 instance HFunctor Random where
-  hmap _ (Random k) = Random k
-  hmap _ (RandomR r k) = RandomR r k
-  hmap f (Interleave m k) = Interleave (f m) k
+  hmap f (Random       k) = Random           (f . k)
+  hmap f (RandomR r    k) = RandomR r        (f . k)
+  hmap f (Interleave m k) = Interleave (f m) (f . k)
   {-# INLINE hmap #-}
 
 instance Effect Random where
-  handle state handler (Random    k) = Random    (handler . (<$ state) . k)
-  handle state handler (RandomR r k) = RandomR r (handler . (<$ state) . k)
+  handle state handler (Random       k) = Random                            (handler . (<$ state) . k)
+  handle state handler (RandomR r    k) = RandomR r                         (handler . (<$ state) . k)
   handle state handler (Interleave m k) = Interleave (handler (m <$ state)) (handler . fmap k)
 
 
 -- | Run a random computation starting from a given generator.
 --
---   prop> run (runRandom (PureGen a) (pure b)) == (PureGen a, b)
+--   prop> run (runRandom (PureGen a) (pure b)) === (PureGen a, b)
 runRandom :: g -> RandomC g m a -> m (g, a)
 runRandom g = runState g . runRandomC
 
 -- | Run a random computation starting from a given generator and discarding the final generator.
 --
---   prop> run (evalRandom (PureGen a) (pure b)) == b
+--   prop> run (evalRandom (PureGen a) (pure b)) === b
 evalRandom :: Functor m => g -> RandomC g m a -> m a
 evalRandom g = fmap snd . runRandom g
 
 -- | Run a random computation starting from a given generator and discarding the final result.
 --
---   prop> run (execRandom (PureGen a) (pure b)) == PureGen a
+--   prop> run (execRandom (PureGen a) (pure b)) === PureGen a
 execRandom :: Functor m => g -> RandomC g m a -> m g
 execRandom g = fmap fst . runRandom g
 
@@ -63,7 +69,7 @@
 evalRandomIO m = liftIO R.newStdGen >>= flip evalRandom m
 
 newtype RandomC g m a = RandomC { runRandomC :: StateC g m a }
-  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus, MonadTrans)
+  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus, MonadTrans)
 
 instance (Carrier sig m, Effect sig, R.RandomGen g) => MonadRandom (RandomC g m) where
   getRandom = RandomC $ do
diff --git a/src/Control/Effect/Reader.hs b/src/Control/Effect/Reader.hs
--- a/src/Control/Effect/Reader.hs
+++ b/src/Control/Effect/Reader.hs
@@ -1,32 +1,38 @@
 {-# LANGUAGE DeriveFunctor, ExistentialQuantification, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, StandaloneDeriving, TypeOperators, UndecidableInstances #-}
 module Control.Effect.Reader
-( Reader(..)
+( -- * Reader effect
+  Reader(..)
 , ask
 , asks
 , local
+  -- * Reader carrier
 , runReader
 , ReaderC(..)
+  -- * Re-exports
+, Carrier
+, Member
+, run
 ) where
 
 import Control.Applicative (Alternative(..), liftA2)
 import Control.Effect.Carrier
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.IO.Unlift
 import Control.Monad.Trans.Class
 import Prelude hiding (fail)
 
 data Reader r m k
-  = Ask (r -> k)
-  | forall b . Local (r -> r) (m b) (b -> k)
+  = Ask (r -> m k)
+  | forall b . Local (r -> r) (m b) (b -> m k)
 
-deriving instance Functor (Reader r m)
+deriving instance Functor m => Functor (Reader r m)
 
 instance HFunctor (Reader r) where
-  hmap _ (Ask k)       = Ask k
-  hmap f (Local g m k) = Local g (f m) k
+  hmap f (Ask k)       = Ask           (f . k)
+  hmap f (Local g m k) = Local g (f m) (f . k)
 
 instance Effect (Reader r) where
   handle state handler (Ask k)       = Ask (handler . (<$ state) . k)
@@ -34,27 +40,27 @@
 
 -- | Retrieve the environment value.
 --
---   prop> run (runReader a ask) == a
+--   prop> run (runReader a ask) === a
 ask :: (Member (Reader r) sig, Carrier sig m) => m r
 ask = send (Ask pure)
 
 -- | Project a function out of the current environment value.
 --
---   prop> snd (run (runReader a (asks (applyFun f)))) == applyFun f a
+--   prop> snd (run (runReader a (asks (applyFun f)))) === applyFun f a
 asks :: (Member (Reader r) sig, Carrier sig m) => (r -> a) -> m a
 asks f = send (Ask (pure . f))
 
 -- | Run a computation with an environment value locally modified by the passed function.
 --
---   prop> run (runReader a (local (applyFun f) ask)) == applyFun f a
---   prop> run (runReader a ((,,) <$> ask <*> local (applyFun f) ask <*> ask)) == (a, applyFun f a, a)
+--   prop> run (runReader a (local (applyFun f) ask)) === applyFun f a
+--   prop> run (runReader a ((,,) <$> ask <*> local (applyFun f) ask <*> ask)) === (a, applyFun f a, a)
 local :: (Member (Reader r) sig, Carrier sig m) => (r -> r) -> m a -> m a
 local f m = send (Local f m pure)
 
 
 -- | Run a 'Reader' effect with the passed environment value.
 --
---   prop> run (runReader a (pure b)) == b
+--   prop> run (runReader a (pure b)) === b
 runReader :: r -> ReaderC r m a -> m a
 runReader r c = runReaderC c r
 {-# INLINE runReader #-}
@@ -86,6 +92,10 @@
   fail = ReaderC . const . fail
   {-# INLINE fail #-}
 
+instance MonadFix m => MonadFix (ReaderC s m) where
+  mfix f = ReaderC (\ r -> mfix (runReader r . f))
+  {-# INLINE mfix #-}
+
 instance MonadIO m => MonadIO (ReaderC r m) where
   liftIO = ReaderC . const . liftIO
   {-# INLINE liftIO #-}
@@ -105,7 +115,7 @@
 instance Carrier sig m => Carrier (Reader r :+: sig) (ReaderC r m) where
   eff (L (Ask       k)) = ReaderC (\ r -> runReader r (k r))
   eff (L (Local f m k)) = ReaderC (\ r -> runReader (f r) m) >>= k
-  eff (R other)         = ReaderC (\ r -> eff (handlePure (runReader r) other))
+  eff (R other)         = ReaderC (\ r -> eff (hmap (runReader r) other))
   {-# INLINE eff #-}
 
 
diff --git a/src/Control/Effect/Resource.hs b/src/Control/Effect/Resource.hs
--- a/src/Control/Effect/Resource.hs
+++ b/src/Control/Effect/Resource.hs
@@ -1,35 +1,36 @@
 {-# LANGUAGE DeriveFunctor, ExistentialQuantification, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, RankNTypes, ScopedTypeVariables, StandaloneDeriving, TypeApplications, TypeOperators, UndecidableInstances #-}
 module Control.Effect.Resource
-( Resource(..)
+( -- * Resource effect
+  Resource(..)
 , bracket
 , bracketOnError
 , finally
 , onException
+  -- * Resource carrier
 , runResource
-, withResource
 , ResourceC(..)
 ) where
 
 import           Control.Applicative (Alternative(..))
 import           Control.Effect.Carrier
 import           Control.Effect.Reader
-import           Control.Effect.Sum
 import qualified Control.Exception as Exc
 import           Control.Monad (MonadPlus(..))
 import           Control.Monad.Fail
+import           Control.Monad.Fix
 import           Control.Monad.IO.Class
 import           Control.Monad.IO.Unlift
 import           Control.Monad.Trans.Class
 
 data Resource m k
-  = forall resource any output . Resource (m resource) (resource -> m any) (resource -> m output) (output -> k)
-  | forall resource any output . OnError  (m resource) (resource -> m any) (resource -> m output) (output -> k)
+  = forall resource any output . Resource (m resource) (resource -> m any) (resource -> m output) (output -> m k)
+  | forall resource any output . OnError  (m resource) (resource -> m any) (resource -> m output) (output -> m k)
 
-deriving instance Functor (Resource m)
+deriving instance Functor m => Functor (Resource m)
 
 instance HFunctor Resource where
-  hmap f (Resource acquire release use k) = Resource (f acquire) (f . release) (f . use) k
-  hmap f (OnError acquire release use k)  = OnError  (f acquire) (f . release) (f . use) k
+  hmap f (Resource acquire release use k) = Resource (f acquire) (f . release) (f . use) (f . k)
+  hmap f (OnError acquire release use k)  = OnError  (f acquire) (f . release) (f . use) (f . k)
 
 instance Effect Resource where
   handle state handler (Resource acquire release use k) = Resource (handler (acquire <$ state)) (handler . fmap release) (handler . fmap use) (handler . fmap k)
@@ -75,24 +76,34 @@
         -> m a
 onException act end = bracketOnError (pure ()) (const end) (const act)
 
-runResource :: (forall x . m x -> IO x) -- ^ "unlifting" function to run the carrier in 'IO'
+-- Not exposed due to its potential to silently drop effects (#180).
+unliftResource :: (forall x . m x -> IO x) -- ^ "unlifting" function to run the carrier in 'IO'
             -> ResourceC m a
             -> m a
-runResource handler = runReader (Handler handler) . runResourceC
+unliftResource handler = runReader (Handler handler) . runResourceC
 
--- | A helper for 'runResource' that uses 'withRunInIO' to automatically
--- select a correct unlifting function.
-withResource :: MonadUnliftIO m
-               => ResourceC m a
-               -> m a
-withResource r = withRunInIO (\f -> runHandler (Handler f) r)
+-- | Executes a 'Resource' effect. Because this runs using 'MonadUnliftIO',
+-- invocations of 'runResource' must happen at the "bottom" of a stack of
+-- effect invocations, i.e. before the use of any monads that lack such
+-- instances, such as 'StateC':
+--
+-- @
+--   runM
+--   . runResource
+--   . runState @Int 1
+--   $ myComputation
+-- @
+runResource :: MonadUnliftIO m
+            => ResourceC m a
+            -> m a
+runResource r = withRunInIO (\f -> runHandler (Handler f) r)
 
 newtype ResourceC m a = ResourceC { runResourceC :: ReaderC (Handler m) m a }
-  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus)
+  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus)
 
 instance MonadUnliftIO m => MonadUnliftIO (ResourceC m) where
   askUnliftIO = ResourceC . ReaderC $ \(Handler h) ->
-    withUnliftIO $ \u -> pure (UnliftIO $ \r -> unliftIO u (runResource h r))
+    withUnliftIO $ \u -> pure (UnliftIO $ \r -> unliftIO u (unliftResource h r))
 
 instance MonadTrans ResourceC where
   lift = ResourceC . lift
diff --git a/src/Control/Effect/Resumable.hs b/src/Control/Effect/Resumable.hs
--- a/src/Control/Effect/Resumable.hs
+++ b/src/Control/Effect/Resumable.hs
@@ -1,12 +1,18 @@
-{-# LANGUAGE DeriveAnyClass, DeriveFunctor, DerivingStrategies, ExistentialQuantification, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, KindSignatures, MultiParamTypeClasses, RankNTypes, StandaloneDeriving, TypeOperators, UndecidableInstances #-}
+{-# LANGUAGE DeriveFunctor, DerivingStrategies, ExistentialQuantification, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, RankNTypes, StandaloneDeriving, TypeOperators, UndecidableInstances #-}
 module Control.Effect.Resumable
-( Resumable(..)
+( -- * Resumable effect
+  Resumable(..)
 , throwResumable
 , SomeError(..)
+  -- * Resumable carriers
 , runResumable
 , ResumableC(..)
 , runResumableWith
 , ResumableWithC(..)
+  -- * Re-exports
+, Carrier
+, Member
+, run
 ) where
 
 import Control.Applicative (Alternative(..))
@@ -14,38 +20,42 @@
 import Control.Effect.Carrier
 import Control.Effect.Error
 import Control.Effect.Reader
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 import Data.Functor.Classes
 
 -- | Errors which can be resumed with values of some existentially-quantified type.
-data Resumable err (m :: * -> *) k
-  = forall a . Resumable (err a) (a -> k)
+data Resumable err m k
+  = forall a . Resumable (err a) (a -> m k)
 
-deriving instance Functor (Resumable err m)
-deriving instance HFunctor (Resumable err)
-deriving instance Effect (Resumable err)
+deriving instance Functor m => Functor (Resumable err m)
 
+instance HFunctor (Resumable err) where
+  hmap f (Resumable err k) = Resumable err (f . k)
+
+instance Effect (Resumable err) where
+  handle state handler (Resumable err k) = Resumable err (handler . (<$ state) . k)
+
 -- | Throw an error which can be resumed with a value of its result type.
 --
---   prop> run (runResumable (throwResumable (Identity a))) == Left (SomeError (Identity a))
+--   prop> run (runResumable (throwResumable (Identity a))) === Left (SomeError (Identity a))
 throwResumable :: (Member (Resumable err) sig, Carrier sig m) => err a -> m a
 throwResumable err = send (Resumable err pure)
 
 
 -- | An error at some existentially-quantified type index.
-data SomeError (err :: * -> *)
+data SomeError err
   = forall a . SomeError (err a)
 
 -- | Equality for 'SomeError' is determined by an 'Eq1' instance for the error type.
 --
 --   Note that since we can’t tell whether the type indices are equal, let alone what 'Eq' instance to use for them, the comparator passed to 'liftEq' always returns 'True'. Thus, 'SomeError' is best used with type-indexed GADTs for the error type.
 --
---   prop> SomeError (Identity a) == SomeError (Identity b)
---   prop> (SomeError (Const a) == SomeError (Const b)) == (a == b)
+--   prop> SomeError (Identity a) === SomeError (Identity b)
+--   prop> (SomeError (Const a) === SomeError (Const b)) == (a == b)
 instance Eq1 err => Eq (SomeError err) where
   SomeError exc1 == SomeError exc2 = liftEq (const (const True)) exc1 exc2
 
@@ -53,8 +63,8 @@
 --
 --   Note that since we can’t tell whether the type indices are equal, let alone what 'Ord' instance to use for them, the comparator passed to 'liftCompare' always returns 'EQ'. Thus, 'SomeError' is best used with type-indexed GADTs for the error type.
 --
---   prop> (SomeError (Identity a) `compare` SomeError (Identity b)) == EQ
---   prop> (SomeError (Const a) `compare` SomeError (Const b)) == (a `compare` b)
+--   prop> (SomeError (Identity a) `compare` SomeError (Identity b)) === EQ
+--   prop> (SomeError (Const a) `compare` SomeError (Const b)) === (a `compare` b)
 instance Ord1 err => Ord (SomeError err) where
   SomeError exc1 `compare` SomeError exc2 = liftCompare (const (const EQ)) exc1 exc2
 
@@ -62,8 +72,8 @@
 --
 --   Note that since we can’t tell what 'Show' instance to use for the type index, the functions passed to 'liftShowsPrec' always return the empty 'ShowS'. Thus, 'SomeError' is best used with type-indexed GADTs for the error type.
 --
---   prop> show (SomeError (Identity a)) == "SomeError (Identity )"
---   prop> show (SomeError (Const a)) == ("SomeError (Const " ++ showsPrec 11 a ")")
+--   prop> show (SomeError (Identity a)) === "SomeError (Identity )"
+--   prop> show (SomeError (Const a)) === ("SomeError (Const " ++ showsPrec 11 a ")")
 instance Show1 err => Show (SomeError err) where
   showsPrec d (SomeError err) = showsUnaryWith (liftShowsPrec (const (const id)) (const id)) "SomeError" d err
 
@@ -77,12 +87,12 @@
 
 -- | Run a 'Resumable' effect, returning uncaught errors in 'Left' and successful computations’ values in 'Right'.
 --
---   prop> run (runResumable (pure a)) == Right @(SomeError Identity) @Int a
+--   prop> run (runResumable (pure a)) === Right @(SomeError Identity) @Int a
 runResumable :: ResumableC err m a -> m (Either (SomeError err) a)
 runResumable = runError . runResumableC
 
 newtype ResumableC err m a = ResumableC { runResumableC :: ErrorC (SomeError err) m a }
-  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus, MonadTrans)
+  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus, MonadTrans)
 
 instance (Carrier sig m, Effect sig) => Carrier (Resumable err :+: sig) (ResumableC err m) where
   eff (L (Resumable err _)) = ResumableC (throwError (SomeError err))
@@ -96,15 +106,15 @@
 --
 --   >>> data Err a where Err :: Int -> Err Int
 --
---   prop> run (runResumableWith (\ (Err b) -> pure (1 + b)) (pure a)) == a
---   prop> run (runResumableWith (\ (Err b) -> pure (1 + b)) (throwResumable (Err a))) == 1 + a
+--   prop> run (runResumableWith (\ (Err b) -> pure (1 + b)) (pure a)) === a
+--   prop> run (runResumableWith (\ (Err b) -> pure (1 + b)) (throwResumable (Err a))) === 1 + a
 runResumableWith :: (forall x . err x -> m x)
                  -> ResumableWithC err m a
                  -> m a
 runResumableWith with = runReader (Handler with) . runResumableWithC
 
 newtype ResumableWithC err m a = ResumableWithC { runResumableWithC :: ReaderC (Handler err m) m a }
-  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus)
+  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus)
 
 instance MonadTrans (ResumableWithC err) where
   lift = ResumableWithC . lift
diff --git a/src/Control/Effect/State/Internal.hs b/src/Control/Effect/State/Internal.hs
--- a/src/Control/Effect/State/Internal.hs
+++ b/src/Control/Effect/State/Internal.hs
@@ -1,41 +1,45 @@
-{-# LANGUAGE DeriveAnyClass, DeriveFunctor, ExplicitForAll, FlexibleContexts, FlexibleInstances, KindSignatures, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
+{-# LANGUAGE DeriveAnyClass, DeriveFunctor, DeriveGeneric, DerivingStrategies, ExplicitForAll, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
 module Control.Effect.State.Internal
-( State(..)
+( -- * State effect
+  State(..)
 , get
 , gets
 , put
 , modify
 , modifyLazy
+  -- * Re-exports
+, Member
 ) where
 
 import Control.Effect.Carrier
-import Control.Effect.Sum
+import GHC.Generics (Generic1)
 import Prelude hiding (fail)
 
-data State s (m :: * -> *) k
-  = Get (s -> k)
-  | Put s k
-  deriving (Functor, HFunctor, Effect)
+data State s m k
+  = Get (s -> m k)
+  | Put s (m k)
+  deriving stock (Functor, Generic1)
+  deriving anyclass (HFunctor, Effect)
 
 -- | Get the current state value.
 --
---   prop> snd (run (runState a get)) == a
+--   prop> snd (run (runState a get)) === a
 get :: (Member (State s) sig, Carrier sig m) => m s
 get = send (Get pure)
 {-# INLINEABLE get #-}
 
 -- | Project a function out of the current state value.
 --
---   prop> snd (run (runState a (gets (applyFun f)))) == applyFun f a
+--   prop> snd (run (runState a (gets (applyFun f)))) === applyFun f a
 gets :: (Member (State s) sig, Carrier sig m) => (s -> a) -> m a
 gets f = send (Get (pure . f))
 {-# INLINEABLE gets #-}
 
 -- | Replace the state value with a new value.
 --
---   prop> fst (run (runState a (put b))) == b
---   prop> snd (run (runState a (get <* put b))) == a
---   prop> snd (run (runState a (put b *> get))) == b
+--   prop> fst (run (runState a (put b))) === b
+--   prop> snd (run (runState a (get <* put b))) === a
+--   prop> snd (run (runState a (put b *> get))) === b
 put :: (Member (State s) sig, Carrier sig m) => s -> m ()
 put s = send (Put s (pure ()))
 {-# INLINEABLE put #-}
@@ -43,7 +47,7 @@
 -- | Replace the state value with the result of applying a function to the current state value.
 --   This is strict in the new state.
 --
---   prop> fst (run (runState a (modify (+1)))) == (1 + a :: Integer)
+--   prop> fst (run (runState a (modify (+1)))) === (1 + a :: Integer)
 modify :: (Member (State s) sig, Carrier sig m) => (s -> s) -> m ()
 modify f = do
   a <- get
diff --git a/src/Control/Effect/State/Lazy.hs b/src/Control/Effect/State/Lazy.hs
--- a/src/Control/Effect/State/Lazy.hs
+++ b/src/Control/Effect/State/Lazy.hs
@@ -1,23 +1,23 @@
-{-# LANGUAGE DeriveFunctor, ExplicitForAll, FlexibleContexts, FlexibleInstances, KindSignatures, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
+{-# LANGUAGE DeriveFunctor, ExplicitForAll, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
 module Control.Effect.State.Lazy
-( State (..)
-, get
-, gets
-, put
-, modify
-, modifyLazy
-, StateC(..)
+( -- * State effect
+  module State
+  -- * Lazy state carrier
 , runState
 , evalState
 , execState
+, StateC(..)
+  -- * Re-exports
+, Carrier
+, run
 ) where
 
 import Control.Applicative (Alternative(..))
 import Control.Effect.Carrier
-import Control.Effect.Sum
-import Control.Effect.State.Internal
+import Control.Effect.State.Internal as State
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 import Prelude hiding (fail)
@@ -55,6 +55,10 @@
   fail s = StateC (const (fail s))
   {-# INLINE fail #-}
 
+instance MonadFix m => MonadFix (StateC s m) where
+  mfix f = StateC (\ s -> mfix (runState s . f . snd))
+  {-# INLINE mfix #-}
+
 instance MonadIO m => MonadIO (StateC s m) where
   liftIO io = StateC (\ s -> (,) s <$> liftIO io)
   {-# INLINE liftIO #-}
@@ -75,22 +79,22 @@
 --   More programs terminate with lazy state than strict state, but injudicious
 --   use of lazy state may lead to thunk buildup.
 --
---   prop> run (runState a (pure b)) == (a, b)
---   prop> take 5 . snd . run $ runState () (traverse pure [1..]) == [1,2,3,4,5]
+--   prop> run (runState a (pure b)) === (a, b)
+--   prop> take 5 . snd . run $ runState () (traverse pure [1..]) === [1,2,3,4,5]
 runState :: s -> StateC s m a -> m (s, a)
 runState s c = runStateC c s
 {-# INLINE[3] runState #-}
 
 -- | Run a lazy 'State' effect, yielding the result value and discarding the final state.
 --
---   prop> run (evalState a (pure b)) == b
+--   prop> run (evalState a (pure b)) === b
 evalState :: forall s m a . Functor m => s -> StateC s m a -> m a
 evalState s = fmap snd . runState s
 {-# INLINE[3] evalState #-}
 
 -- | Run a lazy 'State' effect, yielding the final state and discarding the return value.
 --
---   prop> run (execState a (pure b)) == a
+--   prop> run (execState a (pure b)) === a
 execState :: forall s m a . Functor m => s -> StateC s m a -> m s
 execState s = fmap fst . runState s
 {-# INLINE[3] execState #-}
diff --git a/src/Control/Effect/State/Strict.hs b/src/Control/Effect/State/Strict.hs
--- a/src/Control/Effect/State/Strict.hs
+++ b/src/Control/Effect/State/Strict.hs
@@ -1,44 +1,44 @@
-{-# LANGUAGE DeriveFunctor, ExplicitForAll, FlexibleContexts, FlexibleInstances, KindSignatures, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
+{-# LANGUAGE DeriveFunctor, ExplicitForAll, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
 module Control.Effect.State.Strict
-( State (..)
-, get
-, gets
-, put
-, modify
-, modifyLazy
-, StateC(..)
+( -- * State effect
+  module State
+  -- * Strict state carrier
 , runState
 , evalState
 , execState
+, StateC(..)
+  -- * Re-exports
+, Carrier
+, run
 ) where
 
 import Control.Applicative (Alternative(..))
 import Control.Effect.Carrier
-import Control.Effect.State.Internal
-import Control.Effect.Sum
+import Control.Effect.State.Internal as State
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 import Prelude hiding (fail)
 
 -- | Run a 'State' effect starting from the passed value.
 --
---   prop> run (runState a (pure b)) == (a, b)
+--   prop> run (runState a (pure b)) === (a, b)
 runState :: s -> StateC s m a -> m (s, a)
 runState s x = runStateC x s
 {-# INLINE[3] runState #-}
 
 -- | Run a 'State' effect, yielding the result value and discarding the final state.
 --
---   prop> run (evalState a (pure b)) == b
+--   prop> run (evalState a (pure b)) === b
 evalState :: forall s m a . Functor m => s -> StateC s m a -> m a
 evalState s = fmap snd . runState s
 {-# INLINE[3] evalState #-}
 
 -- | Run a 'State' effect, yielding the final state and discarding the return value.
 --
---   prop> run (execState a (pure b)) == a
+--   prop> run (execState a (pure b)) === a
 execState :: forall s m a . Functor m => s -> StateC s m a -> m s
 execState s = fmap fst . runState s
 {-# INLINE[3] execState #-}
@@ -75,6 +75,10 @@
 instance MonadFail m => MonadFail (StateC s m) where
   fail s = StateC (const (fail s))
   {-# INLINE fail #-}
+
+instance MonadFix m => MonadFix (StateC s m) where
+  mfix f = StateC (\ s -> mfix (runState s . f . snd))
+  {-# INLINE mfix #-}
 
 instance MonadIO m => MonadIO (StateC s m) where
   liftIO io = StateC (\ s -> (,) s <$> liftIO io)
diff --git a/src/Control/Effect/Sum.hs b/src/Control/Effect/Sum.hs
--- a/src/Control/Effect/Sum.hs
+++ b/src/Control/Effect/Sum.hs
@@ -1,30 +1,18 @@
-{-# LANGUAGE DeriveFunctor, FlexibleInstances, KindSignatures, MultiParamTypeClasses, TypeOperators #-}
+{-# LANGUAGE DeriveGeneric, DeriveTraversable, FlexibleInstances, KindSignatures, MultiParamTypeClasses, TypeOperators #-}
 module Control.Effect.Sum
 ( (:+:)(..)
 , Member(..)
-, send
 ) where
 
-import Control.Effect.Carrier
+import GHC.Generics (Generic1)
 
 data (f :+: g) (m :: * -> *) k
   = L (f m k)
   | R (g m k)
-  deriving (Eq, Functor, Ord, Show)
+  deriving (Eq, Foldable, Functor, Generic1, Ord, Show, Traversable)
 
 infixr 4 :+:
 
-instance (HFunctor l, HFunctor r) => HFunctor (l :+: r) where
-  hmap f (L l) = L (hmap f l)
-  hmap f (R r) = R (hmap f r)
-
-  fmap' f (L l) = L (fmap' f l)
-  fmap' f (R r) = R (fmap' f r)
-
-instance (Effect l, Effect r) => Effect (l :+: r) where
-  handle state handler (L l) = L (handle state handler l)
-  handle state handler (R r) = R (handle state handler r)
-
 class Member (sub :: (* -> *) -> (* -> *)) sup where
   inj :: sub m a -> sup m a
   prj :: sup m a -> Maybe (sub m a)
@@ -42,9 +30,3 @@
   inj = R . inj
   prj (R g) = prj g
   prj _     = Nothing
-
-
--- | Construct a request for an effect to be interpreted by some handler later on.
-send :: (Member effect sig, Carrier sig m) => effect m (m a) -> m a
-send = eff . inj
-{-# INLINE send #-}
diff --git a/src/Control/Effect/Trace.hs b/src/Control/Effect/Trace.hs
--- a/src/Control/Effect/Trace.hs
+++ b/src/Control/Effect/Trace.hs
@@ -1,31 +1,39 @@
-{-# LANGUAGE DeriveAnyClass, DeriveFunctor, DerivingStrategies, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, KindSignatures, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
+{-# LANGUAGE DeriveAnyClass, DeriveFunctor, DeriveGeneric, DerivingStrategies, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
 module Control.Effect.Trace
-( Trace(..)
+( -- * Trace effect
+  Trace(..)
 , trace
+  -- * Trace carriers
 , runTraceByPrinting
 , TraceByPrintingC(..)
 , runTraceByIgnoring
 , TraceByIgnoringC(..)
 , runTraceByReturning
 , TraceByReturningC(..)
+  -- * Re-exports
+, Carrier
+, Member
+, run
 ) where
 
 import Control.Applicative (Alternative(..))
 import Control.Effect.Carrier
 import Control.Effect.State
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 import Data.Bifunctor (first)
+import GHC.Generics (Generic1)
 import System.IO
 
-data Trace (m :: * -> *) k = Trace
+data Trace m k = Trace
   { traceMessage :: String
-  , traceCont    :: k
-  } deriving stock Functor
-    deriving anyclass (HFunctor, Effect)
+  , traceCont    :: m k
+  }
+  deriving stock (Functor, Generic1)
+  deriving anyclass (HFunctor, Effect)
 
 -- | Append a message to the trace log.
 trace :: (Member Trace sig, Carrier sig m) => String -> m ()
@@ -37,7 +45,7 @@
 runTraceByPrinting = runTraceByPrintingC
 
 newtype TraceByPrintingC m a = TraceByPrintingC { runTraceByPrintingC :: m a }
-  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus)
+  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus)
 
 instance MonadTrans TraceByPrintingC where
   lift = TraceByPrintingC
@@ -51,12 +59,12 @@
 
 -- | Run a 'Trace' effect, ignoring all traces.
 --
---   prop> run (runTraceByIgnoring (trace a *> pure b)) == b
+--   prop> run (runTraceByIgnoring (trace a *> pure b)) === b
 runTraceByIgnoring :: TraceByIgnoringC m a -> m a
 runTraceByIgnoring = runTraceByIgnoringC
 
 newtype TraceByIgnoringC m a = TraceByIgnoringC { runTraceByIgnoringC :: m a }
-  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus)
+  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus)
 
 instance MonadTrans TraceByIgnoringC where
   lift = TraceByIgnoringC
@@ -70,12 +78,12 @@
 
 -- | Run a 'Trace' effect, returning all traces as a list.
 --
---   prop> run (runTraceByReturning (trace a *> trace b *> pure c)) == ([a, b], c)
+--   prop> run (runTraceByReturning (trace a *> trace b *> pure c)) === ([a, b], c)
 runTraceByReturning :: Functor m => TraceByReturningC m a -> m ([String], a)
 runTraceByReturning = fmap (first reverse) . runState [] . runTraceByReturningC
 
 newtype TraceByReturningC m a = TraceByReturningC { runTraceByReturningC :: StateC [String] m a }
-  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus, MonadTrans)
+  deriving newtype (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus, MonadTrans)
 
 instance (Carrier sig m, Effect sig) => Carrier (Trace :+: sig) (TraceByReturningC m) where
   eff (L (Trace m k)) = TraceByReturningC (modify (m :)) *> k
diff --git a/src/Control/Effect/Writer.hs b/src/Control/Effect/Writer.hs
--- a/src/Control/Effect/Writer.hs
+++ b/src/Control/Effect/Writer.hs
@@ -1,35 +1,41 @@
 {-# LANGUAGE DeriveFunctor, ExistentialQuantification, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, ScopedTypeVariables, StandaloneDeriving, TypeOperators, UndecidableInstances #-}
 module Control.Effect.Writer
-( Writer(..)
+( -- * Writer effect
+  Writer(..)
 , tell
 , listen
 , listens
 , censor
+  -- * Writer carrier
 , runWriter
 , execWriter
 , WriterC(..)
+  -- * Re-exports
+, Carrier
+, Member
+, run
 ) where
 
 import Control.Applicative (Alternative(..))
 import Control.Effect.Carrier
 import Control.Effect.State
-import Control.Effect.Sum
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fail
+import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 
 data Writer w m k
-  = Tell w k
-  | forall a . Listen (m a) (w -> a -> k)
-  | forall a . Censor (w -> w) (m a) (a -> k)
+  = Tell w (m k)
+  | forall a . Listen (m a) (w -> a -> m k)
+  | forall a . Censor (w -> w) (m a) (a -> m k)
 
-deriving instance Functor (Writer w m)
+deriving instance Functor m => Functor (Writer w m)
 
 instance HFunctor (Writer w) where
-  hmap _ (Tell w     k) = Tell w         k
-  hmap f (Listen   m k) = Listen   (f m) k
-  hmap f (Censor g m k) = Censor g (f m) k
+  hmap f (Tell w     k) = Tell w         (f       k)
+  hmap f (Listen   m k) = Listen   (f m) ((f .) . k)
+  hmap f (Censor g m k) = Censor g (f m) (f     . k)
   {-# INLINE hmap #-}
 
 instance Effect (Writer w) where
@@ -40,29 +46,29 @@
 
 -- | Write a value to the log.
 --
---   prop> fst (run (runWriter (mapM_ (tell . Sum) (0 : ws)))) == foldMap Sum ws
+--   prop> fst (run (runWriter (mapM_ (tell . Sum) (0 : ws)))) === foldMap Sum ws
 tell :: (Member (Writer w) sig, Carrier sig m) => w -> m ()
 tell w = send (Tell w (pure ()))
 {-# INLINE tell #-}
 
 -- | Run a computation, returning the pair of its output and its result.
 --
---   prop> run (runWriter (fst <$ tell (Sum a) <*> listen @(Sum Integer) (tell (Sum b)))) == (Sum a <> Sum b, Sum b)
+--   prop> run (runWriter (fst <$ tell (Sum a) <*> listen @(Sum Integer) (tell (Sum b)))) === (Sum a <> Sum b, Sum b)
 listen :: (Member (Writer w) sig, Carrier sig m) => m a -> m (w, a)
 listen m = send (Listen m (curry pure))
 {-# INLINE listen #-}
 
 -- | Run a computation, applying a function to its output and returning the pair of the modified output and its result.
 --
---   prop> run (runWriter (fst <$ tell (Sum a) <*> listens @(Sum Integer) (applyFun f) (tell (Sum b)))) == (Sum a <> Sum b, applyFun f (Sum b))
+--   prop> run (runWriter (fst <$ tell (Sum a) <*> listens @(Sum Integer) (applyFun f) (tell (Sum b)))) === (Sum a <> Sum b, applyFun f (Sum b))
 listens :: (Member (Writer w) sig, Carrier sig m) => (w -> b) -> m a -> m (b, a)
 listens f m = send (Listen m (curry pure . f))
 {-# INLINE listens #-}
 
 -- | Run a computation, modifying its output with the passed function.
 --
---   prop> run (execWriter (censor (applyFun f) (tell (Sum a)))) == applyFun f (Sum a)
---   prop> run (execWriter (tell (Sum a) *> censor (applyFun f) (tell (Sum b)) *> tell (Sum c))) == (Sum a <> applyFun f (Sum b) <> Sum c)
+--   prop> run (execWriter (censor (applyFun f) (tell (Sum a)))) === applyFun f (Sum a)
+--   prop> run (execWriter (tell (Sum a) *> censor (applyFun f) (tell (Sum b)) *> tell (Sum c))) === (Sum a <> applyFun f (Sum b) <> Sum c)
 censor :: (Member (Writer w) sig, Carrier sig m) => (w -> w) -> m a -> m a
 censor f m = send (Censor f m pure)
 {-# INLINE censor #-}
@@ -70,14 +76,14 @@
 
 -- | Run a 'Writer' effect with a 'Monoid'al log, producing the final log alongside the result value.
 --
---   prop> run (runWriter (tell (Sum a) *> pure b)) == (Sum a, b)
+--   prop> run (runWriter (tell (Sum a) *> pure b)) === (Sum a, b)
 runWriter :: Monoid w => WriterC w m a -> m (w, a)
 runWriter = runState mempty . runWriterC
 {-# INLINE runWriter #-}
 
 -- | Run a 'Writer' effect with a 'Monoid'al log, producing the final log and discarding the result value.
 --
---   prop> run (execWriter (tell (Sum a) *> pure b)) == Sum a
+--   prop> run (execWriter (tell (Sum a) *> pure b)) === Sum a
 execWriter :: (Monoid w, Functor m) => WriterC w m a -> m w
 execWriter = fmap fst . runWriter
 {-# INLINE execWriter #-}
@@ -87,7 +93,7 @@
 --
 --   This is based on a post Gabriel Gonzalez made to the Haskell mailing list: https://mail.haskell.org/pipermail/libraries/2013-March/019528.html
 newtype WriterC w m a = WriterC { runWriterC :: StateC w m a }
-  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadIO, MonadPlus, MonadTrans)
+  deriving (Alternative, Applicative, Functor, Monad, MonadFail, MonadFix, MonadIO, MonadPlus, MonadTrans)
 
 instance (Monoid w, Carrier sig m, Effect sig) => Carrier (Writer w :+: sig) (WriterC w m) where
   eff (L (Tell w     k)) = WriterC $ do
diff --git a/test/Control/Effect/NonDet/Spec.hs b/test/Control/Effect/NonDet/Spec.hs
--- a/test/Control/Effect/NonDet/Spec.hs
+++ b/test/Control/Effect/NonDet/Spec.hs
@@ -1,6 +1,7 @@
-module Control.Effect.NonDet.Spec where
+module Control.Effect.NonDet.Spec
+( spec
+) where
 
-import Control.Effect
 import Control.Effect.Error
 import Control.Effect.NonDet
 import Control.Effect.State
diff --git a/test/Control/Effect/Spec.hs b/test/Control/Effect/Spec.hs
--- a/test/Control/Effect/Spec.hs
+++ b/test/Control/Effect/Spec.hs
@@ -1,18 +1,17 @@
 {-# LANGUAGE FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, MultiWayIf, TemplateHaskell, TypeApplications, TypeOperators, UndecidableInstances #-}
 {-# OPTIONS_GHC -O2 -fplugin Test.Inspection.Plugin #-}
-module Control.Effect.Spec where
+module Control.Effect.Spec
+( spec
+) where
 
-import Control.Effect
 import Control.Effect.Carrier
 import Control.Effect.Error
 import Control.Effect.Fail
 import Control.Effect.Reader
 import Control.Effect.State
-import Control.Effect.Sum
 import Prelude hiding (fail)
 import Test.Hspec
 import Test.Inspection as Inspection
-import Test.Inspection.Plugin
 
 spec :: Spec
 spec = do
@@ -29,7 +28,7 @@
 askEnv :: (Member (Reader env) sig, Carrier sig m) => HasEnv env m env
 askEnv = ask
 
-runEnv :: Carrier sig m => env -> HasEnv env (ReaderC env m) a -> HasEnv env m a
+runEnv :: env -> HasEnv env (ReaderC env m) a -> HasEnv env m a
 runEnv r = HasEnv . runReader r . runHasEnv
 
 
@@ -111,13 +110,12 @@
 countBoth :: Int -> (Int, (Float, ()))
 countBoth n = run . runState n . runState (fromIntegral n) $ go where
   go = do
-    int <- get @Int
+    n <- get @Int
     if
       | n == 0         -> pure ()
       | n `mod` 2 == 0 -> modify @Float (+ 1) *> modify @Int pred *> go
-      | otherwise     -> modify @Int pred    *> go
+      | otherwise      -> modify @Int pred    *> go
 
 throwing :: Int -> Either Int String
 throwing n = run $ runError go
   where go = if n > 10 then throwError @Int 42 else pure "fine"
-
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,4 +1,6 @@
-module Main where
+module Main
+( main
+) where
 
 import qualified Control.Effect.Spec
 import qualified Control.Effect.NonDet.Spec
