content: -- | A capability is a type class over a monad which specifies the effects that
  -- a function is allowed to perform. Capabilities differ from traditional monad
  -- transformer type classes in that they are completely independent of the way
  -- the monad is constructed. A state capability can for instance be implemented
  -- as a lens on a field in a larger state monad, or an error capability could
  -- provide for throwing only a subset of the errors of an error monad.
  --
  -- This library defines several standard, reusable capabilities that replace the
  -- mtl's monad-transformer type classes. Because capabilities are not tied to
  -- a particular implementation of the monad, they cannot be discharged by
  -- instance resolution. Instead this library provides combinators in the form of
  -- newtypes with instances, to be used with deriving-via. To learn about
  -- deriving via, watch Baldur Blondal's introductory video
  -- <https://skillsmatter.com/skillscasts/10934-lightning-talk-stolen-instances-taste-just-fine>.
  --
  -- By way of comparison, with the mtl you would write something like
  --
  -- @
  -- foo :: (MonadReader E, MonadState S) => a -> m ()
  -- @
  --
  -- You can use @foo@ at type @a -> ReaderT E (State S)@. But you can't use @foo@
  -- with the @ReaderT@ pattern
  -- <https://www.fpcomplete.com/blog/2017/06/readert-design-pattern>. With this
  -- library, you would instead have:
  --
  -- @
  -- foo :: (HasReader "conf" E, HasState "st" S) => a -> m ()
  -- @
  --
  -- Where @"conf"@ and @"st"@ are the names (also referred to as tags) of the
  -- capabilities demanded by foo. Contrary to the mtl, capabilities are named,
  -- rather than disambiguated by the type of their implied state, or exception.
  -- This makes it easy to have multiple state capabilities.
  --
  -- To /provide/ these capabilities, for instance with the ReaderT pattern, do as
  -- follows (for a longer form tutorial, check the
  -- <https://github.com/tweag/capability#readme README>):
  --
  -- @
  -- newtype MyM a = MyM (ReaderT (E, IORef s))
  --   deriving (Functor, Applicative, Monad)
  --   deriving (HasState "st" Int) via
  --     ReaderIORef (Rename 2 (Pos 2 ()
  --     (MonadReader (ReaderT (E, IORef s) IO))))
  --   deriving (HasReader "conf" Int) via
  --     (Rename 1 (Pos 1 ()
  --     (MonadReader (ReaderT (E, IORef s) IO))))
  -- @
  --
  -- Then you can use @foo@ at type @MyM@. Or any other type which can provide
  -- these capabilites.
  --
  -- === Functional capabilities
  --
  -- When writing applications, as opposed to libraries, a capability /name/ often
  -- determines its type parameters. It can be tiresome to write
  --
  -- @
  -- f :: HasReader "config" Config m => …
  -- @
  --
  -- over and over again.
  --
  -- To avoid this, each capability comes with a /functional/—here
  -- @HasReader\'@—variant (in this terminology @HasReader@ is
  -- /relational/). Where the type is deduced from the capability's name. The
  -- mapping from name to type is done with the @'Capability.TypeOf.TypeOf'@
  -- family, which is re-exported by every capability module.
  --
  -- @
  -- type instance TypeOf Symbol "config" = Config
  --
  -- f :: HasReader' "config" m => …
  -- @
  --
  -- == Module structure
  --
  -- Each module introduces a capability type class (or several related type
  -- classes). Each class comes with a number of instances on newtypes (each
  -- newtype should be seen as a combinator to be used with deriving-via to
  -- provide the capability). Many newtypes come from the common
  -- "Capability.Accessors" module (re-exported by each of the other modules),
  -- which in particular contains a number of ways to address components of a data
  -- type using the generic-lens library.
  --
  -- * "Capability.Reader" reader effects
  -- * "Capability.State" state effects
  -- * "Capability.Writer" writer effects
  -- * "Capability.Error" throw and catch errors
  -- * "Capability.Source" streaming in effect
  -- * "Capability.Sink" streaming out effect (aka generators)
  --
  -- The effects are not all independent:
  --
  -- >     Source   Sink
  -- >     /   \    /   \
  -- >    /     \  /     \
  -- > Reader   State    Writer
  --
  -- "Capability.Source" and "Capability.Sink" have just a method each, and no laws.
  -- The bottom three, familiar from mtl, add methods and laws relating them.
  -- The use of tags allows one to have independent effects that share a superclass.
  -- E.g. @HasState "foo" Int@ and @HasWriter "bar" String@.
  --
  -- Finally there are
  --
  -- * "Capability.Derive"
  -- Which exports a (still experimental) 'Capability.Derive.derive' function,
  -- which lets you run a computation which requires capabilities which are not
  -- directly provided by the ambient monad, but can be derived from the
  -- capabilities provided by the ambient monad.
  -- * "Capability.Reflection"
  -- Which exports 'Capability.Reflection.interpret_' and
  -- 'Capability.Reflection.interpret', which let you define an ad-hoc
  -- interpretation of a capability based on the capabilities provided by the
  -- ambient monad.
  --
  -- == Further considerations
  --
  -- The tags of capabilities can be of any kind, they are not restricted to
  -- symbols. When exporting functions demanding capabilities in libraries, it is
  -- recommended to use a type as follows:
  --
  -- @
  -- data Conf
  --
  -- foo :: HasReader Conf C => m ()
  -- @
  --
  -- This way, @Conf@ can be qualified in case of a name conflict with another
  -- library.
  
  module Capability where
  