-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Extensional capabilities and deriving combinators -- -- Standard capability type classes for extensional effects and -- combinators to derive capability instances with little boilerplate. @package capability @version 0.3.0.0 -- | 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 -- 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. -- --
-- 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 -- TypeOf family, which is re-exported by every -- capability module. -- --
-- type instance TypeOf Symbol "config" = Config -- -- f :: HasReader' "config" m => … ---- --
-- 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. -- -- 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 is -- --
-- data Conf -- -- foo :: HasReader Conf C => m () ---- -- This way, Conf can be qualified in case of a name conflict -- with another library. module Capability -- | Defines newtypes that serve as combinators to compose -- deriving via strategies. module Capability.Accessors -- | Coerce the type in the context m to to. -- -- Example: -- --
-- newtype MyInt = MyInt Int -- newtype MyReader a = MyReader (Reader Int a) -- deriving (HasReader "a" MyInt) via -- Coerce MyInt (MonadReader (Reader Int)) ---- -- Converts the HasReader "a" Int instance of -- MonadReader (Reader Int) to a HasReader "a" -- MyInt instance using Coercible Int MyInt. newtype Coerce (to :: *) m (a :: *) Coerce :: m a -> Coerce m -- | Rename the tag. -- -- Example: -- --
-- newtype MyReader a = MyReader (Reader Int a) -- deriving (HasReader "foo" Int) via -- Rename "bar" (MonadReader (Reader Int)) ---- -- Converts the HasReader "bar" Int instance of -- MonadReader (Reader Int) to a HasReader -- "foo" Int instance by renaming the tag. -- -- Note, that MonadReader itself does not fix a tag, and -- Rename is redundant in this example. -- -- See Pos below for a common use-case. newtype Rename (oldtag :: k) m (a :: *) Rename :: m a -> Rename m -- | Access the record field field in the context m. -- -- Example: -- --
-- data Foo = Foo { foo :: Int }
-- newtype MyReader a = MyReader (Reader Foo a)
-- deriving (HasReader "foo" Int) via
-- Field "foo" () (MonadReader (Reader Foo))
--
--
-- Converts the HasReader () Foo instance of
-- MonadReader (Reader Foo) to a HasReader
-- "foo" Int instance by focusing on the field foo in the
-- Foo record.
--
-- See Rename for a way to change the tag.
newtype Field (field :: Symbol) (oldtag :: k) m (a :: *)
Field :: m a -> Field m
-- | Access the value at position pos in the context m.
--
-- Example:
--
-- -- newtype MyReader a = MyReader (Reader (Int, Bool) a) -- deriving (HasReader 1 Int) via -- Pos 1 () (MonadReader (Reader (Int, Bool))) ---- -- Converts the HasReader () (Int, Bool) instance of -- MonadReader (Reader (Int, Bool)) to a -- HasReader 1 Int instance by focusing on the first -- element of the tuple. -- -- The implied number tag can be renamed to a more descriptive name using -- the Rename combinator: -- --
-- newtype MyReader a = MyReader (Reader (Int, Bool) a) -- deriving (HasReader "foo" Int) via -- Rename 1 (Pos 1 () (MonadReader (Reader (Int, Bool)))) --newtype Pos (pos :: Nat) (oldtag :: k) m (a :: *) Pos :: m a -> Pos m -- | Choose the given constructor in the sum-type in context m. -- -- Example: -- --
-- data MyError = ErrA String | ErrB String -- newtype MyExcept a = MyExcept (ExceptT MyError Identity a) -- deriving (HasThrow "ErrB" String) via -- Ctor "ErrB" () (MonadError (ExceptT MyError Identity)) ---- -- Converts the HasThrow () "MyError" instance of -- MonadError (ExceptT MyError Identity) to a -- HasThrow "ErrB" String instance by wrapping thrown -- Strings in the ErrB constructor. newtype Ctor (ctor :: Symbol) (oldtag :: k) m (a :: *) Ctor :: m a -> Ctor m -- | Skip one level in a monad transformer stack. -- -- Note, that instances generated with this strategy can incur a -- performance penalty. -- -- Example: -- --
-- newtype MyStates a = MyStates (StateT Int (State Bool) a) -- deriving (HasState "foo" Bool) via -- Lift (StateT Int (MonadState (State Bool))) ---- -- Uses the MonadTrans instance of StateT Int to lift the -- HasState "foo" Bool instance of the underlying -- MonadState (State Bool) over the StateT Int -- monad transformer. newtype Lift m (a :: *) Lift :: m a -> Lift m -- | Compose two accessors. -- -- This is not necessary in deriving via clauses, but in places where a -- transformer is expected as a type argument. E.g. wrapError. newtype (:.:) (t2 :: (* -> *) -> * -> *) (t1 :: (* -> *) -> * -> *) (m :: * -> *) (a :: *) (:.:) :: m a -> (:.:) infixr 9 :.: infixr 9 :.: instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad ((Capability.Accessors.:.:) t2 t1 m) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO ((Capability.Accessors.:.:) t2 t1 m) instance GHC.Base.Monad m => GHC.Base.Monad ((Capability.Accessors.:.:) t2 t1 m) instance GHC.Base.Applicative m => GHC.Base.Applicative ((Capability.Accessors.:.:) t2 t1 m) instance GHC.Base.Functor m => GHC.Base.Functor ((Capability.Accessors.:.:) t2 t1 m) instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Accessors.Lift m) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Accessors.Lift m) instance GHC.Base.Monad m => GHC.Base.Monad (Capability.Accessors.Lift m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Accessors.Lift m) instance GHC.Base.Functor m => GHC.Base.Functor (Capability.Accessors.Lift m) instance forall (ctor :: GHC.Types.Symbol) k (oldtag :: k) (m :: * -> *). Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Accessors.Ctor ctor oldtag m) instance forall (ctor :: GHC.Types.Symbol) k (oldtag :: k) (m :: * -> *). Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Accessors.Ctor ctor oldtag m) instance forall (ctor :: GHC.Types.Symbol) k (oldtag :: k) (m :: * -> *). GHC.Base.Monad m => GHC.Base.Monad (Capability.Accessors.Ctor ctor oldtag m) instance forall (ctor :: GHC.Types.Symbol) k (oldtag :: k) (m :: * -> *). GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Accessors.Ctor ctor oldtag m) instance forall (ctor :: GHC.Types.Symbol) k (oldtag :: k) (m :: * -> *). GHC.Base.Functor m => GHC.Base.Functor (Capability.Accessors.Ctor ctor oldtag m) instance forall (pos :: GHC.Types.Nat) k (oldtag :: k) (m :: * -> *). Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Accessors.Pos pos oldtag m) instance forall (pos :: GHC.Types.Nat) k (oldtag :: k) (m :: * -> *). Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Accessors.Pos pos oldtag m) instance forall (pos :: GHC.Types.Nat) k (oldtag :: k) (m :: * -> *). GHC.Base.Monad m => GHC.Base.Monad (Capability.Accessors.Pos pos oldtag m) instance forall (pos :: GHC.Types.Nat) k (oldtag :: k) (m :: * -> *). GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Accessors.Pos pos oldtag m) instance forall (pos :: GHC.Types.Nat) k (oldtag :: k) (m :: * -> *). GHC.Base.Functor m => GHC.Base.Functor (Capability.Accessors.Pos pos oldtag m) instance forall (field :: GHC.Types.Symbol) k (oldtag :: k) (m :: * -> *). Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Accessors.Field field oldtag m) instance forall (field :: GHC.Types.Symbol) k (oldtag :: k) (m :: * -> *). Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Accessors.Field field oldtag m) instance forall (field :: GHC.Types.Symbol) k (oldtag :: k) (m :: * -> *). GHC.Base.Monad m => GHC.Base.Monad (Capability.Accessors.Field field oldtag m) instance forall (field :: GHC.Types.Symbol) k (oldtag :: k) (m :: * -> *). GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Accessors.Field field oldtag m) instance forall (field :: GHC.Types.Symbol) k (oldtag :: k) (m :: * -> *). GHC.Base.Functor m => GHC.Base.Functor (Capability.Accessors.Field field oldtag m) instance forall k (oldtag :: k) (m :: * -> *). Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Accessors.Rename oldtag m) instance forall k (oldtag :: k) (m :: * -> *). Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Accessors.Rename oldtag m) instance forall k (oldtag :: k) (m :: * -> *). GHC.Base.Monad m => GHC.Base.Monad (Capability.Accessors.Rename oldtag m) instance forall k (oldtag :: k) (m :: * -> *). GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Accessors.Rename oldtag m) instance forall k (oldtag :: k) (m :: * -> *). GHC.Base.Functor m => GHC.Base.Functor (Capability.Accessors.Rename oldtag m) instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Accessors.Coerce to m) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Accessors.Coerce to m) instance GHC.Base.Monad m => GHC.Base.Monad (Capability.Accessors.Coerce to m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Accessors.Coerce to m) instance GHC.Base.Functor m => GHC.Base.Functor (Capability.Accessors.Coerce to m) -- | This module defines helper types and type families for working with -- sets of capabilities. module Capability.Constraints -- | Type family used used to express a conjunction of constraints over a -- single type. -- -- Examples: -- --
-- All '[Num, Eq] Int -- -- Equivalent to: (Num Int, Eq Int) -- -- All '[HasReader "foo" Int, HasSink "bar" Float] m -- -- Equivalent to: (HasReader "foo" Int m, HasSink "bar" Float m) --type family All (xs :: [k -> Constraint]) a :: Constraint -- | A Capability takes a type constructor * -> * (e.g., -- a monad) and returns a Constraint. Examples of capabilities -- includ: HasReader "foo" Int, MonadIO, … type Capability = (* -> *) -> Constraint -- | The kind of constraints, like Show a data Constraint -- | Values of type Dict p capture a dictionary for a -- constraint of type p. -- -- e.g. -- --
-- Dict :: Dict (Eq Int) ---- -- captures a dictionary that proves we have an: -- --
-- instance Eq 'Int ---- -- Pattern matching on the Dict constructor will bring this -- instance into scope. data Dict a [Dict] :: forall a. a => Dict a module Capability.Derive -- | Runs an action that requires additional capabilities. -- -- derive @t @derived @ambient act runs act by -- providing both the capabilities in derived and -- ambient. The difference is that ambient capabilities -- are assumed to be available, whereas derived instances are -- provided by t. -- -- derive assumes that t is a newtype defined in the -- form: -- --
-- newtype T m a = T (m a) ---- -- Then derive uses type-class instances for T to provide -- for each of the capabilities in derived. -- -- A common instance of this is wrapError, whereby exceptions -- raised by act can be repackaged in a larger exception type. -- -- The derive function is experimental and is subject to change. derive :: forall t (derived :: [Capability]) (ambient :: [Capability]) m a. (forall x. Coercible (t m x) (m x), All derived (t m), All ambient m) => (forall m'. (All derived m', All ambient m') => m' a) -> m a module Capability.TypeOf -- | Type family associating a tag to the corresponding type. It is -- intended to simplify constraint declarations, by removing the need to -- redundantly specify the type associated to a tag. -- -- It is poly-kinded, which allows users to define their own kind of -- tags. Standard haskell types can also be used as tags by specifying -- the * kind when defining the type family instance. -- -- Defining TypeOf instances for Symbols (typelevel string -- literals) is discouraged. Since symbols all belong to the same global -- namespace, such instances could conflict with others defined in -- external libraries. More generally, as for typeclasses, TypeOf -- instances should always be defined in the same module as the tag type -- to prevent issues due to orphan instances. -- -- Example: -- --
-- import Capability.Reader -- -- data Foo -- data Bar -- type instance TypeOf * Foo = Int -- type instance TypeOf * Bar = String -- -- -- Same as: foo :: HasReader Foo Int M => … -- foo :: HasReader' Foo m => … -- foo = … --type family TypeOf k (s :: k) :: * -- | Defines a capability type class for a state effect. A state capability -- provides a state which can be retrieved with get and set with -- put. As an analogy, each state capability is equivalent to -- making one IORef available in an IO computation -- (except, of course, that a state capability does not have to be -- provided by IO). -- -- This is a very expressive capability. It is often preferable to -- restrict to less powerful capabilities such as -- Capability.Reader, Capability.Writer, or -- Capability.Stream. module Capability.State -- | State capability -- -- An instance should fulfill the following laws. At this point these -- laws are not definitive, see -- https://github.com/haskell/mtl/issues/5. -- --
-- get @t >>= \s1 -> get @t >>= \s2 -> pure (s1, s2) = get @t >>= \s -> pure (s, s) ---- --
-- get @t >>= \_ -> put @t s = put @t s ---- --
-- put @t s1 >> put @t s2 = put @t s2 ---- --
-- put @t s >> get @t = put @t s >> pure s ---- --
-- state @t f = get @t >>= \s -> let (a, s') = f s in put @t s' >> pure a --class (Monad m, HasSource tag s m, HasSink tag s m) => HasState (tag :: k) (s :: *) (m :: * -> *) | tag m -> s -- | For technical reasons, this method needs an extra proxy argument. You -- only need it if you are defining new instances of 'HasState. -- Otherwise, you will want to use state. See state for -- more documentation. state_ :: HasState tag s m => Proxy# tag -> (s -> (a, s)) -> m a -- | get @tag retrieve the current state of the state capability -- tag. get :: forall tag s m. HasState tag s m => m s -- | put @tag s replace the current state of the state capability -- tag with s. put :: forall tag s m. HasState tag s m => s -> m () -- | state @tag f lifts a pure state computation f to a -- monadic action in an arbitrary monad m with capability -- HasState. -- -- Given the current state s of the state capability -- tag and (a, s') = f s, update the state to -- s' and return a. state :: forall tag s m a. HasState tag s m => (s -> (a, s)) -> m a -- | modify @tag f given the current state s of the state -- capability tag and s' = f s, updates the state of -- the capability tag to s'. modify :: forall tag s m. HasState tag s m => (s -> s) -> m () -- | Same as modify but strict in the new state. modify' :: forall tag s m. HasState tag s m => (s -> s) -> m () -- | gets @tag f retrieves the image, by f of the current -- state of the state capability tag. -- --
-- gets @tag f = f <$> get @tag --gets :: forall tag s m a. HasState tag s m => (s -> a) -> m a -- | Execute the given state action on a sub-component of the current state -- as defined by the given transformer t. The set of retained -- capabilities must be passed as @cs. If no capabilities are required, -- None can be used. -- -- Examples: -- --
-- foo :: HasState "foo" Int m => m ()
-- zoom @"foo" @(Field "foo" "foobar") @None foo
-- :: (HasField' "foobar" record Int, HasState "foobar" record m) => m ()
--
-- zoom @"foo" @(Field "foo" "foobar") @('[MonadIO]) bar
-- :: ( HasField' "foobar" record Int, HasState "foobar" record m
-- , MonadIO m) => m ()
--
-- foo :: HasState "foo" Int m => m ()
-- bar :: (MonadIO m, HasState "foo" Int m) => m ()
--
--
-- Note: the HasField' constraint comes from the
-- generic-lens package.
--
-- This function is experimental and subject to change. See
-- https://github.com/tweag/capability/issues/46.
zoom :: forall innertag t (cs :: [Capability]) inner m a. (forall x. Coercible (t m x) (m x), HasState innertag inner (t m), All cs m) => (forall m'. All (HasState innertag inner : cs) m' => m' a) -> m a
-- | Type synonym using the TypeOf type family to specify
-- HasState constraints without having to specify the type
-- associated to a tag.
type HasState' (tag :: k) = HasState tag (TypeOf k tag)
-- | Type family associating a tag to the corresponding type. It is
-- intended to simplify constraint declarations, by removing the need to
-- redundantly specify the type associated to a tag.
--
-- It is poly-kinded, which allows users to define their own kind of
-- tags. Standard haskell types can also be used as tags by specifying
-- the * kind when defining the type family instance.
--
-- Defining TypeOf instances for Symbols (typelevel string
-- literals) is discouraged. Since symbols all belong to the same global
-- namespace, such instances could conflict with others defined in
-- external libraries. More generally, as for typeclasses, TypeOf
-- instances should always be defined in the same module as the tag type
-- to prevent issues due to orphan instances.
--
-- Example:
--
-- -- import Capability.Reader -- -- data Foo -- data Bar -- type instance TypeOf * Foo = Int -- type instance TypeOf * Bar = String -- -- -- Same as: foo :: HasReader Foo Int M => … -- foo :: HasReader' Foo m => … -- foo = … --type family TypeOf k (s :: k) :: * -- | Derive HasState from m's MonadState instance. newtype MonadState (m :: * -> *) (a :: *) MonadState :: m a -> MonadState -- | Derive a state monad from a reader over an IORef. -- -- Example: -- --
-- newtype MyState m a = MyState (ReaderT (IORef Int) m a) -- deriving (Functor, Applicative, Monad) -- deriving HasState "foo" Int via -- ReaderIORef (MonadReader (ReaderT (IORef Int) m)) ---- -- See ReaderRef for a more generic strategy. newtype ReaderIORef m a ReaderIORef :: m a -> ReaderIORef m a -- | Derive a state monad from a reader over a mutable reference. -- -- Mutable references are available in a PrimMonad. The -- corresponding PrimState has to match the MCState of the -- reference. This constraint makes a stand-alone deriving clause -- necessary. -- -- Example: -- --
-- newtype MyState m a = MyState (ReaderT (IORef Int) m a) -- deriving (Functor, Applicative, Monad) -- deriving via ReaderRef (MonadReader (ReaderT (IORef Int) m)) -- instance (PrimMonad m, PrimState m ~ PrimState IO) -- => HasState "foo" Int (MyState m) ---- -- See ReaderIORef for a specialized version over IORef. newtype ReaderRef m (a :: *) ReaderRef :: m a -> ReaderRef m -- | Defines a capability for computations that consume a stream of values -- as part of their execution. -- -- Programs comsuming streams of data are common. Examples: rolling up -- input events. Sources are similar to Python generators. -- -- This can be thought of as a reader capability where there's no -- guarantee that one reads the same value each time. -- -- The HasSource capability enables separating the logic -- responsible for emitting events from that responsible for collecting -- or handling them. The name is because a source is needed to produce -- the locally consumed stream. module Capability.Source -- | Sourcing capability. -- -- An instance does not need to fulfill any additional laws besides the -- monad laws. class Monad m => HasSource (tag :: k) (a :: *) (m :: * -> *) | tag m -> a -- | For technical reasons, this method needs an extra proxy argument. You -- only need it if you are defining new instances of HasSource. -- Otherwise, you will want to use await. See await for -- more documentation. await_ :: HasSource tag a m => Proxy# tag -> m a -- | await @tag a takes a from the source capability -- tag. await :: forall tag a m. HasSource tag a m => m a -- | awaits @tag retrieves the image by f of the -- environment of the reader capability tag. -- --
-- awaits @tag f = f <$> await @tag --awaits :: forall tag r m a. HasSource tag r m => (r -> a) -> m a -- | Type synonym using the TypeOf type family to specify -- HasSource constraints without having to specify the type -- associated to a tag. type HasSource' (tag :: k) = HasSource tag (TypeOf k tag) -- | Type family associating a tag to the corresponding type. It is -- intended to simplify constraint declarations, by removing the need to -- redundantly specify the type associated to a tag. -- -- It is poly-kinded, which allows users to define their own kind of -- tags. Standard haskell types can also be used as tags by specifying -- the * kind when defining the type family instance. -- -- Defining TypeOf instances for Symbols (typelevel string -- literals) is discouraged. Since symbols all belong to the same global -- namespace, such instances could conflict with others defined in -- external libraries. More generally, as for typeclasses, TypeOf -- instances should always be defined in the same module as the tag type -- to prevent issues due to orphan instances. -- -- Example: -- --
-- import Capability.Reader -- -- data Foo -- data Bar -- type instance TypeOf * Foo = Int -- type instance TypeOf * Bar = String -- -- -- Same as: foo :: HasReader Foo Int M => … -- foo :: HasReader' Foo m => … -- foo = … --type family TypeOf k (s :: k) :: * -- | Derive HasSource from m's MonadReader instance. newtype MonadReader (m :: * -> *) (a :: *) MonadReader :: m a -> MonadReader -- | Convert a pure state monad into a reader monad. -- -- Pure meaning that the monad stack does not allow catching -- exceptions. Otherwise, an exception occurring in the action passed to -- local could cause the context to remain modified outside of -- the call to local. E.g. -- --
-- local @tag (const r') (throw MyException) -- `catch` \MyException -> ask @tag ---- -- returns r' instead of the previous value. -- -- Note, that no MonadIO instance is provided, as this would -- allow catching exceptions. -- -- See ReadState. newtype ReadStatePure (m :: * -> *) (a :: *) ReadStatePure :: m a -> ReadStatePure -- | Convert a state monad into a reader monad. -- -- Use this if the monad stack allows catching exceptions. -- -- See ReadStatePure. newtype ReadState (m :: * -> *) (a :: *) ReadState :: m a -> ReadState -- | Derive HasState from m's MonadState instance. newtype MonadState (m :: * -> *) (a :: *) MonadState :: m a -> MonadState -- | Derive a state monad from a reader over an IORef. -- -- Example: -- --
-- newtype MyState m a = MyState (ReaderT (IORef Int) m a) -- deriving (Functor, Applicative, Monad) -- deriving HasState "foo" Int via -- ReaderIORef (MonadReader (ReaderT (IORef Int) m)) ---- -- See ReaderRef for a more generic strategy. newtype ReaderIORef m a ReaderIORef :: m a -> ReaderIORef m a -- | Derive a state monad from a reader over a mutable reference. -- -- Mutable references are available in a PrimMonad. The -- corresponding PrimState has to match the MCState of the -- reference. This constraint makes a stand-alone deriving clause -- necessary. -- -- Example: -- --
-- newtype MyState m a = MyState (ReaderT (IORef Int) m a) -- deriving (Functor, Applicative, Monad) -- deriving via ReaderRef (MonadReader (ReaderT (IORef Int) m)) -- instance (PrimMonad m, PrimState m ~ PrimState IO) -- => HasState "foo" Int (MyState m) ---- -- See ReaderIORef for a specialized version over IORef. newtype ReaderRef m (a :: *) ReaderRef :: m a -> ReaderRef m -- | Defines a capability for computations that produce a stream of values -- as part of their execution. -- -- Programs producing streams of data are common. Examples: emitting -- events on input, or emitting events whenever certain conditions are -- observed. streams are similar to Python generators. -- -- The HasSink capability enables separating the logic responsible -- for emitting events from that responsible for collecting or handling -- them. The name is because a sink is needed to consume the locally -- produced stream. -- -- This can be thought of as a writer capability of a list of values -- HasWriter tag [v] with \x -> tell @tag [x] as a -- primitive operation. However, that implementation would be -- inefficient. -- -- For example using the Stream instance, a producer defined using -- this capability can be consumed efficiently in a streaming fashion. module Capability.Sink -- | Sinking capability. -- -- An instance does not need to fulfill any additional laws besides the -- monad laws. class Monad m => HasSink (tag :: k) (a :: *) (m :: * -> *) | tag m -> a -- | For technical reasons, this method needs an extra proxy argument. You -- only need it if you are defining new instances of HasSink. -- Otherwise, you will want to use yield. See yield for -- more documentation. yield_ :: HasSink tag a m => Proxy# tag -> a -> m () -- | yield @tag a emits a in the sink capability -- tag. yield :: forall tag a m. HasSink tag a m => a -> m () -- | Type synonym using the TypeOf type family to specify -- HasSink constraints without having to specify the type -- associated to a tag. type HasSink' (tag :: k) = HasSink tag (TypeOf k tag) -- | Type family associating a tag to the corresponding type. It is -- intended to simplify constraint declarations, by removing the need to -- redundantly specify the type associated to a tag. -- -- It is poly-kinded, which allows users to define their own kind of -- tags. Standard haskell types can also be used as tags by specifying -- the * kind when defining the type family instance. -- -- Defining TypeOf instances for Symbols (typelevel string -- literals) is discouraged. Since symbols all belong to the same global -- namespace, such instances could conflict with others defined in -- external libraries. More generally, as for typeclasses, TypeOf -- instances should always be defined in the same module as the tag type -- to prevent issues due to orphan instances. -- -- Example: -- --
-- import Capability.Reader -- -- data Foo -- data Bar -- type instance TypeOf * Foo = Int -- type instance TypeOf * Bar = String -- -- -- Same as: foo :: HasReader Foo Int M => … -- foo :: HasReader' Foo m => … -- foo = … --type family TypeOf k (s :: k) :: * -- | Accumulate sunk values in a reverse order list. newtype SinkStack m (a :: *) SinkStack :: m a -> SinkStack m -- | Accumulate sunk values in forward order in a difference list. newtype SinkDList m (a :: *) SinkDList :: m a -> SinkDList m -- | Accumulate sunk values with their own monoid. newtype SinkLog m (a :: *) SinkLog :: m a -> SinkLog m -- | Deprecated: Use Sink module Capability.Stream type HasStream = HasSink type HasStream' tag = HasSink' tag -- | yield @tag a emits a in the sink capability -- tag. yield :: forall tag a m. HasSink tag a m => a -> m () type StreamStack = SinkStack type StreamDList = SinkDList type StreamLog = SinkLog -- | Defines a capability type class for a reader effect. A reader provides -- an environment, say an initialization context or a configuration. The -- environment held in the reader effect can be changed (with -- local) within the scope of a sub-computation. Contrary to the -- Capability.State, such a change is local, and does not persist -- when the local call ends. module Capability.Reader -- | Reader capability -- -- An instance should fulfill the following laws. At this point these -- laws are not definitive, see -- https://github.com/haskell/mtl/issues/5. -- --
-- k <*> ask @t = ask @t <**> k ---- --
-- ask @t *> m = m = m <* ask @t ---- --
-- local @t f (ask @t) = fmap f (ask @t) ---- --
-- local @t f . local @t g = local @t (g . f) ---- --
-- local @t f (pure x) = pure x ---- --
-- local @t f (m >>= \x -> k x) = local @t f m >>= \x -> local @t f (k x) ---- --
-- reader @t f = f <$> ask @t --class (Monad m, HasSource tag r m) => HasReader (tag :: k) (r :: *) (m :: * -> *) | tag m -> r -- | For technical reasons, this method needs an extra proxy argument. You -- only need it if you are defining new instances of HasReader. -- Otherwise, you will want to use local. See local for -- more documentation. local_ :: HasReader tag r m => Proxy# tag -> (r -> r) -> m a -> m a -- | For technical reasons, this method needs an extra proxy argument. You -- only need it if you are defining new instances of HasReader. -- Otherwise, you will want to use reader. See reader for -- more documentation. reader_ :: HasReader tag r m => Proxy# tag -> (r -> a) -> m a -- | ask @tag retrieves the environment of the reader capability -- tag. ask :: forall tag r m. HasReader tag r m => m r -- | asks @tag retrieves the image by f of the -- environment of the reader capability tag. -- --
-- asks @tag f = f <$> ask @tag --asks :: forall tag r m a. HasReader tag r m => (r -> a) -> m a -- | local @tag f m runs the monadic action m in a -- modified environment e' = f e, where e is the -- environment of the reader capability tag. Symbolically: -- return e = ask @tag. local :: forall tag r m a. HasReader tag r m => (r -> r) -> m a -> m a -- | reader @tag act lifts a purely environment-dependent action -- act to a monadic action in an arbitrary monad m with -- capability HasReader. -- -- It happens to coincide with asks: reader = asks. reader :: forall tag r m a. HasReader tag r m => (r -> a) -> m a -- | Execute the given reader action on a sub-component of the current -- context as defined by the given transformer t, retaining -- arbitrary capabilities listed in cs. -- -- See the similar zoom function for more details and examples. -- -- This function is experimental and subject to change. See -- https://github.com/tweag/capability/issues/46. magnify :: forall innertag t (cs :: [Capability]) inner m a. (forall x. Coercible (t m x) (m x), HasReader innertag inner (t m), All cs m) => (forall m'. All (HasReader innertag inner : cs) m' => m' a) -> m a -- | Type synonym using the TypeOf type family to specify -- HasReader constraints without having to specify the type -- associated to a tag. type HasReader' (tag :: k) = HasReader tag (TypeOf k tag) -- | Type family associating a tag to the corresponding type. It is -- intended to simplify constraint declarations, by removing the need to -- redundantly specify the type associated to a tag. -- -- It is poly-kinded, which allows users to define their own kind of -- tags. Standard haskell types can also be used as tags by specifying -- the * kind when defining the type family instance. -- -- Defining TypeOf instances for Symbols (typelevel string -- literals) is discouraged. Since symbols all belong to the same global -- namespace, such instances could conflict with others defined in -- external libraries. More generally, as for typeclasses, TypeOf -- instances should always be defined in the same module as the tag type -- to prevent issues due to orphan instances. -- -- Example: -- --
-- import Capability.Reader -- -- data Foo -- data Bar -- type instance TypeOf * Foo = Int -- type instance TypeOf * Bar = String -- -- -- Same as: foo :: HasReader Foo Int M => … -- foo :: HasReader' Foo m => … -- foo = … --type family TypeOf k (s :: k) :: * -- | Derive HasSource from m's MonadReader instance. newtype MonadReader (m :: * -> *) (a :: *) MonadReader :: m a -> MonadReader -- | Convert a pure state monad into a reader monad. -- -- Pure meaning that the monad stack does not allow catching -- exceptions. Otherwise, an exception occurring in the action passed to -- local could cause the context to remain modified outside of -- the call to local. E.g. -- --
-- local @tag (const r') (throw MyException) -- `catch` \MyException -> ask @tag ---- -- returns r' instead of the previous value. -- -- Note, that no MonadIO instance is provided, as this would -- allow catching exceptions. -- -- See ReadState. newtype ReadStatePure (m :: * -> *) (a :: *) ReadStatePure :: m a -> ReadStatePure -- | Convert a state monad into a reader monad. -- -- Use this if the monad stack allows catching exceptions. -- -- See ReadStatePure. newtype ReadState (m :: * -> *) (a :: *) ReadState :: m a -> ReadState -- | Defines capabilities for actions that may fail or throw exceptions, -- and optionally may catch exceptions. -- -- Monads based on IO can use the underlying IO -- exception mechanism to that end. The details of synchronous and -- asynchronous exception handling depend on the strategy used. See -- MonadThrow, SafeExceptions, MonadUnliftIO. -- -- The associated tag can be used to select the exception type, or to -- select a layer in monad transformer stacks. Note, that it is illegal -- to have multiple tags refer to overlapping exception types in the same -- layer. Consider the following example -- --
-- newtype M a = M (IO a) -- deriving (HasThrow "foo" IOException) via -- MonadUnliftIO IO -- deriving (HasThrow "bar" SomeException) via -- MonadUnliftIO IO ---- -- In this case the tags "foo" and "bar" refer to -- overlapping exception types in the same layer, because catch -- @"bar" may also catch an exception thrown under "foo". module Capability.Error -- | Capability to throw exceptions of type e under tag. -- -- HasThrow/HasCatch capabilities at different tags -- should be independent. See HasCatch. class Monad m => HasThrow (tag :: k) (e :: *) (m :: * -> *) | tag m -> e -- | For technical reasons, this method needs an extra proxy argument. You -- only need it if you are defining new instances of HasReader. -- Otherwise, you will want to use throw. See throw for -- more documentation. throw_ :: HasThrow tag e m => Proxy# tag -> e -> m a -- | Throw an exception in the specified exception capability. throw :: forall tag e m a. HasThrow tag e m => e -> m a -- | Capability to catch exceptions of type e under tag. -- -- HasThrow/HasCatch capabilities at different tags -- should be independent. In particular, the following program should -- throw SomeError and not return (). > example :: -- > (HasThrow Left SomeError m, HasCatch Right -- SomeError m) > => m () > example = > catch Left -- > (throw Right SomeError) > _ -> pure () -- -- See wrapError for a way to combine multiple exception types -- into one. class HasThrow tag e m => HasCatch (tag :: k) (e :: *) (m :: * -> *) | tag m -> e -- | For technical reasons, this method needs an extra proxy argument. You -- only need it if you are defining new instances of HasReader. -- Otherwise, you will want to use catch. See catch for -- more documentation. catch_ :: HasCatch tag e m => Proxy# tag -> m a -> (e -> m a) -> m a -- | For technical reasons, this method needs an extra proxy argument. You -- only need it if you are defining new instances of HasReader. -- Otherwise, you will want to use catchJust. See catchJust -- for more documentation. catchJust_ :: HasCatch tag e m => Proxy# tag -> (e -> Maybe b) -> m a -> (b -> m a) -> m a -- | Provide a handler for exceptions thrown in the given action in the -- given exception capability. catch :: forall tag e m a. HasCatch tag e m => m a -> (e -> m a) -> m a -- | Like catch, but only handle the exception if the provided -- function returns Just. catchJust :: forall tag e m a b. HasCatch tag e m => (e -> Maybe b) -> m a -> (b -> m a) -> m a -- | Wrap exceptions inner originating from the given action -- according to the accessor t. Retain arbitrary capabilities -- listed in cs. -- -- Example: -- --
-- wrapError -- @"ComponentError" @(Ctor "ComponentError" "AppError") @'[] -- component -- -- component :: HasError "ComponentError" ComponentError m => m () -- data AppError = ComponentError ComponentError ---- -- This function is experimental and subject to change. See -- https://github.com/tweag/capability/issues/46. wrapError :: forall innertag t (cs :: [Capability]) inner m a. (forall x. Coercible (t m x) (m x), HasCatch innertag inner (t m), All cs m) => (forall m'. All (HasCatch innertag inner : cs) m' => m' a) -> m a -- | Type synonym using the TypeOf type family to specify -- HasThrow constraints without having to specify the type -- associated to a tag. type HasThrow' (tag :: k) = HasThrow tag (TypeOf k tag) -- | Type synonym using the TypeOf type family to specify -- HasCatch constraints without having to specify the type -- associated to a tag. type HasCatch' (tag :: k) = HasCatch tag (TypeOf k tag) -- | Type family associating a tag to the corresponding type. It is -- intended to simplify constraint declarations, by removing the need to -- redundantly specify the type associated to a tag. -- -- It is poly-kinded, which allows users to define their own kind of -- tags. Standard haskell types can also be used as tags by specifying -- the * kind when defining the type family instance. -- -- Defining TypeOf instances for Symbols (typelevel string -- literals) is discouraged. Since symbols all belong to the same global -- namespace, such instances could conflict with others defined in -- external libraries. More generally, as for typeclasses, TypeOf -- instances should always be defined in the same module as the tag type -- to prevent issues due to orphan instances. -- -- Example: -- --
-- import Capability.Reader -- -- data Foo -- data Bar -- type instance TypeOf * Foo = Int -- type instance TypeOf * Bar = String -- -- -- Same as: foo :: HasReader Foo Int M => … -- foo :: HasReader' Foo m => … -- foo = … --type family TypeOf k (s :: k) :: * -- | Derive 'HasError from m's MonadError instance. newtype MonadError m (a :: *) MonadError :: m a -> MonadError m -- | Derive HasThrow from m's MonadThrow instance. newtype MonadThrow (e :: *) m (a :: *) MonadThrow :: m a -> MonadThrow m -- | Derive 'HasCatch from m's 'Control.Monad.Catch.MonadCatch -- instance. newtype MonadCatch (e :: *) m (a :: *) MonadCatch :: m a -> MonadCatch m -- | Derive HasError using the functionality from the -- safe-exceptions package. newtype SafeExceptions (e :: *) m (a :: *) SafeExceptions :: m a -> SafeExceptions m -- | Derive HasError using the functionality from the -- unliftio package. newtype MonadUnliftIO (e :: *) m (a :: *) MonadUnliftIO :: m a -> MonadUnliftIO m -- | Any type that you wish to throw or catch as an exception must be an -- instance of the Exception class. The simplest case is a new -- exception type directly below the root: -- --
-- data MyException = ThisException | ThatException -- deriving Show -- -- instance Exception MyException ---- -- The default method definitions in the Exception class do what -- we need in this case. You can now throw and catch -- ThisException and ThatException as exceptions: -- --
-- *Main> throw ThisException `catch` \e -> putStrLn ("Caught " ++ show (e :: MyException))
-- Caught ThisException
--
--
-- In more complicated examples, you may wish to define a whole hierarchy
-- of exceptions:
--
-- -- --------------------------------------------------------------------- -- -- Make the root exception type for all the exceptions in a compiler -- -- data SomeCompilerException = forall e . Exception e => SomeCompilerException e -- -- instance Show SomeCompilerException where -- show (SomeCompilerException e) = show e -- -- instance Exception SomeCompilerException -- -- compilerExceptionToException :: Exception e => e -> SomeException -- compilerExceptionToException = toException . SomeCompilerException -- -- compilerExceptionFromException :: Exception e => SomeException -> Maybe e -- compilerExceptionFromException x = do -- SomeCompilerException a <- fromException x -- cast a -- -- --------------------------------------------------------------------- -- -- Make a subhierarchy for exceptions in the frontend of the compiler -- -- data SomeFrontendException = forall e . Exception e => SomeFrontendException e -- -- instance Show SomeFrontendException where -- show (SomeFrontendException e) = show e -- -- instance Exception SomeFrontendException where -- toException = compilerExceptionToException -- fromException = compilerExceptionFromException -- -- frontendExceptionToException :: Exception e => e -> SomeException -- frontendExceptionToException = toException . SomeFrontendException -- -- frontendExceptionFromException :: Exception e => SomeException -> Maybe e -- frontendExceptionFromException x = do -- SomeFrontendException a <- fromException x -- cast a -- -- --------------------------------------------------------------------- -- -- Make an exception type for a particular frontend compiler exception -- -- data MismatchedParentheses = MismatchedParentheses -- deriving Show -- -- instance Exception MismatchedParentheses where -- toException = frontendExceptionToException -- fromException = frontendExceptionFromException ---- -- We can now catch a MismatchedParentheses exception as -- MismatchedParentheses, SomeFrontendException or -- SomeCompilerException, but not other types, e.g. -- IOException: -- --
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
-- Caught MismatchedParentheses
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeFrontendException))
-- Caught MismatchedParentheses
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeCompilerException))
-- Caught MismatchedParentheses
-- *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: IOException))
-- *** Exception: MismatchedParentheses
--
class (Typeable e, Show e) => Exception e
toException :: Exception e => e -> SomeException
fromException :: Exception e => SomeException -> Maybe e
-- | Render this exception value in a human-friendly manner.
--
-- Default implementation: show.
displayException :: Exception e => e -> String
-- | The class Typeable allows a concrete representation of a type
-- to be calculated.
class Typeable (a :: k)
instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Error.MonadUnliftIO e m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Error.MonadUnliftIO e m)
instance GHC.Base.Monad m => GHC.Base.Monad (Capability.Error.MonadUnliftIO e m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Error.MonadUnliftIO e m)
instance GHC.Base.Functor m => GHC.Base.Functor (Capability.Error.MonadUnliftIO e m)
instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Error.SafeExceptions e m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Error.SafeExceptions e m)
instance GHC.Base.Monad m => GHC.Base.Monad (Capability.Error.SafeExceptions e m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Error.SafeExceptions e m)
instance GHC.Base.Functor m => GHC.Base.Functor (Capability.Error.SafeExceptions e m)
instance forall k (tag :: k) e (m :: * -> *). (GHC.Exception.Type.Exception e, Control.Monad.Catch.MonadThrow m) => Capability.Error.HasThrow tag e (Capability.Error.MonadCatch e m)
instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Error.MonadCatch e m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Error.MonadCatch e m)
instance GHC.Base.Monad m => GHC.Base.Monad (Capability.Error.MonadCatch e m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Error.MonadCatch e m)
instance GHC.Base.Functor m => GHC.Base.Functor (Capability.Error.MonadCatch e m)
instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Error.MonadThrow e m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Error.MonadThrow e m)
instance GHC.Base.Monad m => GHC.Base.Monad (Capability.Error.MonadThrow e m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Error.MonadThrow e m)
instance GHC.Base.Functor m => GHC.Base.Functor (Capability.Error.MonadThrow e m)
instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Error.MonadError m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Error.MonadError m)
instance GHC.Base.Monad m => GHC.Base.Monad (Capability.Error.MonadError m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Error.MonadError m)
instance GHC.Base.Functor m => GHC.Base.Functor (Capability.Error.MonadError m)
instance forall k (tag :: k) e (t2 :: (* -> *) -> * -> *) (t1 :: (* -> *) -> * -> *) (m :: * -> *). (forall x. GHC.Types.Coercible (m x) (t2 (t1 m) x), GHC.Base.Monad m, Capability.Error.HasThrow tag e (t2 (t1 m))) => Capability.Error.HasThrow tag e ((Capability.Accessors.:.:) t2 t1 m)
instance forall k (tag :: k) e (t2 :: (* -> *) -> * -> *) (t1 :: (* -> *) -> * -> *) (m :: * -> *). (forall x. GHC.Types.Coercible (m x) (t2 (t1 m) x), GHC.Base.Monad m, Capability.Error.HasCatch tag e (t2 (t1 m))) => Capability.Error.HasCatch tag e ((Capability.Accessors.:.:) t2 t1 m)
instance forall k e (m :: * -> *) (tag :: k). (GHC.Exception.Type.Exception e, Control.Monad.IO.Class.MonadIO m) => Capability.Error.HasThrow tag e (Capability.Error.MonadUnliftIO e m)
instance forall k e (m :: * -> *) (tag :: k). (GHC.Exception.Type.Exception e, Control.Monad.IO.Unlift.MonadUnliftIO m) => Capability.Error.HasCatch tag e (Capability.Error.MonadUnliftIO e m)
instance forall k e (m :: * -> *) (tag :: k). (GHC.Exception.Type.Exception e, Control.Monad.Catch.MonadThrow m) => Capability.Error.HasThrow tag e (Capability.Error.SafeExceptions e m)
instance forall k e (m :: * -> *) (tag :: k). (GHC.Exception.Type.Exception e, Control.Monad.Catch.MonadCatch m) => Capability.Error.HasCatch tag e (Capability.Error.SafeExceptions e m)
instance forall k e (m :: * -> *) (tag :: k). (GHC.Exception.Type.Exception e, Control.Monad.Catch.MonadCatch m) => Capability.Error.HasCatch tag e (Capability.Error.MonadCatch e m)
instance forall k e (m :: * -> *) (tag :: k). (GHC.Exception.Type.Exception e, Control.Monad.Catch.MonadThrow m) => Capability.Error.HasThrow tag e (Capability.Error.MonadThrow e m)
instance forall k e (m :: * -> *) (tag :: k). Control.Monad.Error.Class.MonadError e m => Capability.Error.HasThrow tag e (Capability.Error.MonadError m)
instance forall k e (m :: * -> *) (tag :: k). Control.Monad.Error.Class.MonadError e m => Capability.Error.HasCatch tag e (Capability.Error.MonadError m)
instance forall k1 k2 (oldtag :: k2) e (m :: * -> *) (newtag :: k1). Capability.Error.HasCatch oldtag e m => Capability.Error.HasCatch newtag e (Capability.Accessors.Rename oldtag m)
instance forall k (ctor :: GHC.Types.Symbol) sum e (oldtag :: k) (m :: * -> *). (Data.Generics.Sum.Constructors.AsConstructor' ctor sum e, Capability.Error.HasCatch oldtag sum m) => Capability.Error.HasCatch ctor e (Capability.Accessors.Ctor ctor oldtag m)
instance forall k (tag :: k) e (m :: * -> *) (t :: (* -> *) -> * -> *). (Capability.Error.HasCatch tag e m, Control.Monad.Trans.Control.MonadTransControl t, GHC.Base.Monad (t m)) => Capability.Error.HasCatch tag e (Capability.Accessors.Lift (t m))
instance forall k1 k2 (oldtag :: k2) e (m :: * -> *) (newtag :: k1). Capability.Error.HasThrow oldtag e m => Capability.Error.HasThrow newtag e (Capability.Accessors.Rename oldtag m)
instance forall k (ctor :: GHC.Types.Symbol) sum e (oldtag :: k) (m :: * -> *). (Data.Generics.Sum.Constructors.AsConstructor' ctor sum e, Capability.Error.HasThrow oldtag sum m) => Capability.Error.HasThrow ctor e (Capability.Accessors.Ctor ctor oldtag m)
instance forall k (tag :: k) e (m :: * -> *) (t :: (* -> *) -> * -> *). (Capability.Error.HasThrow tag e m, Control.Monad.Trans.Class.MonadTrans t, GHC.Base.Monad (t m)) => Capability.Error.HasThrow tag e (Capability.Accessors.Lift (t m))
-- | Defines a capability type class for writer effects. A writer program
-- can output values with tell. The values output by two
-- consecutive sub-computation are combined using a monoid's
-- mappend.
--
-- The interface of HasWriter follows that of MonadWriter.
-- However, this module does not include a strategy to provide a
-- HasWriter capability from a MonadWriter instance. It
-- is generally a bad idea to use monads such as WriterT, as they
-- tend to leak space, as described in this
-- <https://blog.infinitenegativeutility.com/2016/7/writer-monads-and-space-leaks
-- blog post> by Getty Ritter.
--
-- Instead, you should use the WriterLog strategy that implements
-- the writer monad on a state monad. There is no downside, as using
-- HasWriter instead of HasState directly ensures your code
-- adheres to the writer monad interface and does not misuse the
-- underlying state monad.
module Capability.Writer
-- | Writer capability
--
-- An instance should fulfill the following laws. At this point these
-- laws are not definitive, see
-- https://github.com/haskell/mtl/issues/5.
--
-- -- listen @t (pure a) = pure (a, mempty) ---- --
-- listen @t (tell @t w) = tell @t w >> pure (w, w) ---- --
-- listen @t (m >>= k) = listen @t m >>= \(a, w1) -> listen @t (k a) >>= \(b, w2) -> pure (b, w1 `mappend` w2) ---- --
-- pass @t (tell @t w >> pure (a, f)) = tell @t (f w) >> pure a ---- --
-- writer @t (a, w) = tell @t w >> pure a ---- --
-- import Capability.Reader -- -- data Foo -- data Bar -- type instance TypeOf * Foo = Int -- type instance TypeOf * Bar = String -- -- -- Same as: foo :: HasReader Foo Int M => … -- foo :: HasReader' Foo m => … -- foo = … --type family TypeOf k (s :: k) :: * type WriterLog = SinkLog type StreamLog = SinkLog -- | Accumulate sunk values with their own monoid. newtype SinkLog m (a :: *) SinkLog :: m a -> SinkLog m instance forall k (tag :: k) w (t2 :: (* -> *) -> * -> *) (t1 :: (* -> *) -> * -> *) (m :: * -> *). (forall x. GHC.Types.Coercible (m x) (t2 (t1 m) x), GHC.Base.Monad m, Capability.Writer.HasWriter tag w (t2 (t1 m))) => Capability.Writer.HasWriter tag w ((Capability.Accessors.:.:) t2 t1 m) instance forall k w (tag :: k) (m :: * -> *). (GHC.Base.Monoid w, Capability.State.Internal.Class.HasState tag w m) => Capability.Writer.HasWriter tag w (Capability.Writer.WriterLog m) -- | Defines discouraged instances of writer monad capabilities. module Capability.Writer.Discouraged instance (Capability.Writer.HasWriter tag w m, Control.Monad.Trans.Unlift.MonadTransUnlift t, GHC.Base.Monad (t m)) => Capability.Writer.HasWriter tag w (Capability.Accessors.Lift (t m))