diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,19 @@
 # Revision history for capability
 
+## 0.5.0.0 -- 2021-07-21
+
+* Fix compatibility with GHC 9.0.
+  See [#96](https://github.com/tweag/capability/pull/96)
+
+* Remove `Capability.Writer.Discouraged`.
+  This module incurred a dependency on monad-unlift which is no longer
+  available for GHC 9.0. Given that its use was discouraged, it was deemed best
+  to remove it.
+  See [#96](https://github.com/tweag/capability/pull/96)
+
+* Added `censor` function to `Capability.Writer`.
+  See [#94](https://github.com/tweag/capability/pull/94)
+
 ## 0.4.0.0 -- 2021-03-15
 
 * Fix infinite loop in `writer`.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -72,11 +72,11 @@
 newtype M a = M { runM :: Ctx -> IO a }
   deriving (Functor, Applicative, Monad) via ReaderT Ctx IO
   -- Use DerivingVia to derive a HasReader instance.
-  deriving (HasReader "foo" Int) via
+  deriving (HasReader "foo" Int, HasSource "foo" Int) via
     -- Pick the field foo from the Ctx record in the ReaderT environment.
     Field "foo" "ctx" (MonadReader (ReaderT Ctx IO))
   -- Use DerivingVia to derive a HasState instance.
-  deriving (HasState "bar" Bool) via
+  deriving (HasState "bar" Bool, HasSource "bar" Bool, HasSink "bar" Bool) via
     -- Convert a reader of IORef to a state capability.
     ReaderIORef (Field "bar" "ctx" (MonadReader (ReaderT Ctx IO)))
 
diff --git a/capability.cabal b/capability.cabal
--- a/capability.cabal
+++ b/capability.cabal
@@ -1,5 +1,5 @@
 name: capability
-version: 0.4.0.0
+version: 0.5.0.0
 homepage: https://github.com/tweag/capability
 license: BSD3
 license-file: LICENSE.md
@@ -12,7 +12,7 @@
   CONTRIBUTING.md
   README.md
 cabal-version: 1.18
-tested-with: GHC==8.10.4
+tested-with: GHC==8.10.4, GHC==9.0.1
 synopsis: Extensional capabilities and deriving combinators
 description:
   Standard capability type classes for extensional effects and combinators
@@ -58,23 +58,21 @@
     Capability.Stream
     Capability.TypeOf
     Capability.Writer
-    Capability.Writer.Discouraged
   build-depends:
       base >= 4.14 && < 5.0
-    , constraints >= 0.1 && < 0.13
-    , dlist >= 0.8 && < 0.9
+    , constraints >= 0.1 && < 0.14
+    , dlist >= 0.8 && < 1.1
     , exceptions >= 0.6 && < 0.11
-    , generic-lens >= 2.0 && < 2.1
-    , lens >= 4.16 && < 5.0
+    , generic-lens >= 2.0 && < 2.3
+    , lens >= 4.16 && < 5.1
     , monad-control >= 1.0 && < 1.1
-    , monad-unlift >= 0.2 && < 0.3
     , mtl >= 2.0 && < 3.0
     , mutable-containers >= 0.3 && < 0.4
     , primitive >= 0.6 && < 0.8
     , reflection >= 2.1 && < 2.2
     , safe-exceptions >= 0.1 && < 0.2
     , streaming >= 0.2 && < 0.3
-    , transformers >= 0.5.5 && < 0.6
+    , transformers >= 0.5.5 && < 0.7
     , unliftio >= 0.2 && < 0.3
     , unliftio-core >= 0.1 && < 0.3
   if flag(dev)
diff --git a/examples/Writer.hs b/examples/Writer.hs
--- a/examples/Writer.hs
+++ b/examples/Writer.hs
@@ -21,7 +21,7 @@
 
 -- | Increase a counter using a writer monad.
 useWriter :: HasWriter "count-writer" (Sum Int) m => m ()
-useWriter = do
+useWriter = censor @"count-writer" (*2) {- double the eventual result -} $ do
   -- Add 3 and retrieve result
   ((), count) <- listen @"count-writer" (tell @"count-writer" 3)
   -- Duplicate
@@ -82,9 +82,9 @@
 spec = do
   describe "WriterM" $
     it "evaluates useWriter" $
-      runWriterM useWriter `shouldBe` ((), 6)
+      runWriterM useWriter `shouldBe` ((), 12)
   describe "BadWriterM" $ do
     it "evaluates useWriter" $
-      runBadWriterM useWriter `shouldBe` ((), 6)
+      runBadWriterM useWriter `shouldBe` ((), 12)
     it "evaluates mixWriterState" $
       runBadWriterM mixWriterState `shouldBe` (1, 2)
diff --git a/src/Capability.hs b/src/Capability.hs
--- a/src/Capability.hs
+++ b/src/Capability.hs
@@ -103,11 +103,6 @@
 -- The use of tags allows one to have independent effects that share a superclass.
 -- E.g. @HasState "foo" Int@ and @HasWriter "bar" String@.
 --
--- Some of the capability modules have a “discouraged” companion (such as
--- "Capability.Writer.Discouraged"). These modules contain deriving-via
--- combinators which you can use if you absolutely must: they are correct, but
--- inefficient, so we recommend that you do not.
---
 -- Finally there are
 --
 -- * "Capability.Derive"
diff --git a/src/Capability/Error.hs b/src/Capability/Error.hs
--- a/src/Capability/Error.hs
+++ b/src/Capability/Error.hs
@@ -174,8 +174,8 @@
   , HasCatch innertag inner (t m)
   , All cs m)
   => (forall m'. All (HasCatch innertag inner ': cs) m' => m' a) -> m a
-wrapError =
-  derive @t @'[HasCatch innertag inner] @cs
+wrapError action =
+  derive @t @'[HasCatch innertag inner] @cs action
 {-# INLINE wrapError #-}
 
 -- XXX: Does it make sense to add a HasMask capability similar to @MonadMask@?
diff --git a/src/Capability/Reader/Internal/Class.hs b/src/Capability/Reader/Internal/Class.hs
--- a/src/Capability/Reader/Internal/Class.hs
+++ b/src/Capability/Reader/Internal/Class.hs
@@ -107,8 +107,8 @@
   , HasReader innertag inner (t m)
   , All cs m)
   => (forall m'. All (HasReader innertag inner ': cs) m' => m' a) -> m a
-magnify =
-  derive @t @'[HasReader innertag inner] @cs
+magnify action =
+  derive @t @'[HasReader innertag inner] @cs action
 {-# INLINE magnify #-}
 
 --------------------------------------------------------------------------------
diff --git a/src/Capability/Reflection.hs b/src/Capability/Reflection.hs
--- a/src/Capability/Reflection.hs
+++ b/src/Capability/Reflection.hs
@@ -73,7 +73,7 @@
   Reified tag c m ->
   (forall m'. c m' => m' a) ->
   m a
-interpret_ = interpret @tag @'[] @c
+interpret_ dict action = interpret @tag @'[] @c dict action
 {-# INLINE interpret_ #-}
 
 -- | @interpret \@tag \@ambient dict action@
diff --git a/src/Capability/Source/Internal/Class.hs b/src/Capability/Source/Internal/Class.hs
--- a/src/Capability/Source/Internal/Class.hs
+++ b/src/Capability/Source/Internal/Class.hs
@@ -62,7 +62,7 @@
 
 -- | @awaits \@tag@
 -- retrieves the image by @f@ of the environment
--- of the reader capability @tag@.
+-- of the source capability @tag@.
 --
 -- prop> awaits @tag f = f <$> await @tag
 awaits :: forall tag r m a. HasSource tag r m => (r -> a) -> m a
diff --git a/src/Capability/State/Internal/Class.hs b/src/Capability/State/Internal/Class.hs
--- a/src/Capability/State/Internal/Class.hs
+++ b/src/Capability/State/Internal/Class.hs
@@ -132,8 +132,8 @@
   , HasState innertag inner (t m)
   , All cs m )
   => (forall m'. All (HasState innertag inner ': cs) m' => m' a) -> m a
-zoom =
-  derive @t @'[HasState innertag inner] @cs
+zoom action =
+  derive @t @'[HasState innertag inner] @cs action
 {-# INLINE zoom #-}
 
 --------------------------------------------------------------------------------
diff --git a/src/Capability/Writer.hs b/src/Capability/Writer.hs
--- a/src/Capability/Writer.hs
+++ b/src/Capability/Writer.hs
@@ -31,6 +31,7 @@
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TupleSections #-}
 {-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE TypeInType #-}
 {-# LANGUAGE TypeFamilies #-}
@@ -47,6 +48,7 @@
   , tell
   , listen
   , pass
+  , censor
   -- * Functional capability
   , HasWriter'
   , TypeOf
@@ -146,6 +148,17 @@
 pass :: forall tag w m a. HasWriter tag w m => m (a, w -> w) -> m a
 pass = pass_ (proxy# @tag)
 {-# INLINE pass #-}
+
+censor_ :: forall k (tag :: k) w m a. HasWriter tag w m => Proxy# tag -> (w -> w) -> m a -> m a
+censor_ tag f m = pass_ tag $ (,f) <$> m
+
+-- | @censor \@tag f m@
+--   is an action that executes the action @m@ and applies the
+--   function @f@ to the output of the writer capability @tag@,
+--   leaving the return value unchanged.
+censor :: forall tag w m a. HasWriter tag w m => (w -> w) -> m a -> m a
+censor = censor_ (proxy# @tag)
+{-# INLINE censor #-}
 
 -- | Compose two accessors.
 deriving via ((t2 :: (Type -> Type) -> Type -> Type) ((t1 :: (Type -> Type) -> Type -> Type) m))
diff --git a/src/Capability/Writer/Discouraged.hs b/src/Capability/Writer/Discouraged.hs
deleted file mode 100644
--- a/src/Capability/Writer/Discouraged.hs
+++ /dev/null
@@ -1,55 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE InstanceSigs #-}
-{-# LANGUAGE MagicHash #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeApplications #-}
-{-# LANGUAGE UndecidableInstances #-}
-
-{-# OPTIONS_GHC -Wno-orphans #-}
-{-# OPTIONS_GHC -Wno-simplifiable-class-constraints #-}
-
--- | Defines discouraged instances of writer monad capabilities.
-
-module Capability.Writer.Discouraged
-  ( ) where
-
-import Capability.Accessors
-import Capability.Writer
-import Control.Monad.Trans.Class (lift)
-import Control.Monad.Trans.Unlift (MonadTransUnlift, Unlift(..), askUnlift)
-import Data.Coerce (coerce)
-import GHC.Exts (Proxy#)
-
--- | Lift one layer in a monad transformer stack.
---
--- Note, that if the 'HasWriter' instance is based on 'HasState', then it is
--- more efficient to apply 'Lift' to the underlying state capability. E.g.
--- you should favour
---
--- > deriving (HasWriter tag w) via
--- >   WriterLog (Lift (SomeTrans (MonadState SomeStateMonad)))
---
--- over
---
--- > deriving (HasWriter tag w) via
--- >   Lift (SomeTrans (WriterLog (MonadState SomeStateMonad)))
-instance
-  -- MonadTransUnlift constraint requires -Wno-simplifiable-class-constraints
-  (HasWriter tag w m, MonadTransUnlift t, Monad (t m))
-  => HasWriter tag w (Lift (t m))
-  where
-    writer_ :: forall a. Proxy# tag -> (a, w) -> Lift (t m) a
-    writer_ _ = coerce @((a, w) -> t m a) $ lift . writer @tag
-    {-# INLINE writer_ #-}
-    listen_ :: forall a. Proxy# tag -> Lift (t m) a -> Lift (t m) (a, w)
-    listen_ _ = coerce @(t m a -> t m (a, w)) $ \m -> do
-      u <- askUnlift
-      lift $ listen @tag $ unlift u m
-    {-# INLINE listen_ #-}
-    pass_ :: forall a. Proxy# tag -> Lift (t m) (a, w -> w) -> Lift (t m) a
-    pass_ _ = coerce @(t m (a, w -> w) -> t m a) $ \m -> do
-      u <- askUnlift
-      lift $ pass @tag $ unlift u m
-    {-# INLINE pass_ #-}
