-- 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.1.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. -- --
-- 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) -- | 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. -- -- Example: -- --
-- wrapError -- @"AppError" @"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 outertag innertag t outer inner m a. (forall x. Coercible (t m x) (m x), forall m'. HasCatch outertag outer m' => HasCatch innertag inner (t m'), HasCatch outertag outer m) => (forall m'. HasCatch innertag inner m' => m' a) -> m a -- | 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 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 => 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 ask. See ask for more -- documentation. ask_ :: HasReader tag r m => Proxy# 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. -- -- See zoom. -- -- This function is experimental and subject to change. See -- https://github.com/tweag/capability/issues/46. magnify :: forall outertag innertag t outer inner m a. (forall x. Coercible (t m x) (m x), forall m'. HasReader outertag outer m' => HasReader innertag inner (t m'), HasReader outertag outer m) => (forall m'. HasReader innertag inner m' => m' a) -> m a -- | Derive HasReader 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 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 => 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 get. See get for more -- documentation. get_ :: HasState tag s m => Proxy# 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 put. See put for more -- documentation. put_ :: HasState tag s m => Proxy# tag -> s -> m () -- | 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. -- -- Example: -- --
-- zoom @"foobar" @"foo" @(Field "foo" "foobar") foo
-- :: HasState "foobar" FooBar m => m ()
--
-- foo :: HasState "foo" Int m => m ()
-- data FooBar = FooBar { foo :: Int, bar :: String }
--
--
-- This function is experimental and subject to change. See
-- https://github.com/tweag/capability/issues/46.
zoom :: forall outertag innertag t outer inner m a. (forall x. Coercible (t m x) (m x), forall m'. HasState outertag outer m' => HasState innertag inner (t m'), HasState outertag outer m) => (forall m'. HasState innertag inner m' => m' a) -> m a
-- | 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 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 --class (Monoid w, Monad m) => HasWriter (tag :: k) (w :: *) (m :: * -> *) | tag m -> w -- | 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 writer. See writer for -- more documentation. writer_ :: HasWriter tag w m => Proxy# tag -> (a, w) -> 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 tell. See tell for more -- documentation. tell_ :: HasWriter tag w m => Proxy# tag -> w -> m () -- | 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 listen. See listen for -- more documentation. listen_ :: HasWriter tag w m => Proxy# tag -> m a -> m (a, w) -- | 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 pass. See pass for more -- documentation. pass_ :: HasWriter tag w m => Proxy# tag -> m (a, w -> w) -> m a -- | writer @tag (a, w) lifts a pure writer action (a, w) -- to a monadic action in an arbitrary monad m with capability -- HasWriter. -- -- Appends w to the output of the writer capability tag -- and returns the value a. writer :: forall tag w m a. HasWriter tag w m => (a, w) -> m a -- | tell @tag w appends w to the output of the writer -- capability tag. tell :: forall tag w m. HasWriter tag w m => w -> m () -- | listen @tag m executes the action m and returns the -- output of m in the writer capability tag along with -- result of m. Appends the output of m to the output -- of the writer capability tag. listen :: forall tag w m a. HasWriter tag w m => m a -> m (a, w) -- | pass @tag m executes the action m. Assuming -- m returns (a, f) and appends w to the -- output of the writer capability tag. pass @tag m -- instead appends w' = f w to the output and returns -- a. pass :: forall tag w m a. HasWriter tag w m => m (a, w -> w) -> m a newtype WriterLog m a WriterLog :: m a -> WriterLog m a instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Writer.WriterLog m) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Writer.WriterLog m) instance GHC.Base.Monad m => GHC.Base.Monad (Capability.Writer.WriterLog m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Writer.WriterLog m) instance GHC.Base.Functor m => GHC.Base.Functor (Capability.Writer.WriterLog 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 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 HasStream capability enables separating the logic -- responsible for emitting events from that responsible for collecting -- or handling them. -- -- 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.Stream -- | Streaming capability. -- -- An instance does not need to fulfill any additional laws besides the -- monad laws. class Monad m => HasStream (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 HasReader. -- Otherwise, you will want to use yield. See yield for -- more documentation. yield_ :: HasStream tag a m => Proxy# tag -> a -> m () -- | yield @tag a emits a in the stream capability -- tag. yield :: forall tag a m. HasStream tag a m => a -> m () -- | Accumulate streamed values in a reverse order list. newtype StreamStack m (a :: *) StreamStack :: m a -> StreamStack m -- | Accumulate streamed values in forward order in a difference list. newtype StreamDList m (a :: *) StreamDList :: m a -> StreamDList m instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Stream.StreamDList m) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Stream.StreamDList m) instance GHC.Base.Monad m => GHC.Base.Monad (Capability.Stream.StreamDList m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Stream.StreamDList m) instance GHC.Base.Functor m => GHC.Base.Functor (Capability.Stream.StreamDList m) instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Capability.Stream.StreamStack m) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Capability.Stream.StreamStack m) instance GHC.Base.Monad m => GHC.Base.Monad (Capability.Stream.StreamStack m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Capability.Stream.StreamStack m) instance GHC.Base.Functor m => GHC.Base.Functor (Capability.Stream.StreamStack m) instance forall k (tag :: k) a (t2 :: (* -> *) -> * -> *) (t1 :: (* -> *) -> * -> *) (m :: * -> *). (forall x. GHC.Types.Coercible (m x) (t2 (t1 m) x), GHC.Base.Monad m, Capability.Stream.HasStream tag a (t2 (t1 m))) => Capability.Stream.HasStream tag a ((Capability.Accessors.:.:) t2 t1 m) instance forall k (tag :: k) a (m :: * -> *). Capability.Writer.HasWriter tag (Data.DList.DList a) m => Capability.Stream.HasStream tag a (Capability.Stream.StreamDList m) instance forall k (tag :: k) a (m :: * -> *). Capability.State.Internal.Class.HasState tag [a] m => Capability.Stream.HasStream tag a (Capability.Stream.StreamStack m) instance forall k (m :: * -> *) (tag :: k) a. GHC.Base.Monad m => Capability.Stream.HasStream tag a (Streaming.Internal.Stream (Data.Functor.Of.Of a) m) instance forall k (tag :: k) a (m :: * -> *) (t :: (* -> *) -> * -> *). (Capability.Stream.HasStream tag a m, Control.Monad.Trans.Class.MonadTrans t, GHC.Base.Monad (t m)) => Capability.Stream.HasStream tag a (Capability.Accessors.Lift (t 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))