capability-0.4.0.0: Extensional capabilities and deriving combinators
Safe HaskellNone
LanguageHaskell2010

Capability.Reader

Description

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.

Synopsis

Relational capability

class (Monad m, HasSource tag r m) => HasReader (tag :: k) (r :: Type) (m :: Type -> Type) | tag m -> r where Source #

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

Methods

local_ :: Proxy# tag -> (r -> r) -> m a -> m a Source #

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.

reader_ :: Proxy# tag -> (r -> a) -> m a Source #

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.

Instances

Instances details
(HasReader tag r m, MonadTransControl t, Monad (t m)) => HasReader (tag :: k) r (Lift (t m)) Source #

Lift one layer in a monad transformer stack.

Instance details

Defined in Capability.Reader.Internal.Strategies

Methods

local_ :: Proxy# tag -> (r -> r) -> Lift (t m) a -> Lift (t m) a Source #

reader_ :: Proxy# tag -> (r -> a) -> Lift (t m) a Source #

(HasState tag r m, MonadMask m) => HasReader (tag :: k) r (ReadState m) Source # 
Instance details

Defined in Capability.Reader.Internal.Strategies

Methods

local_ :: Proxy# tag -> (r -> r) -> ReadState m a -> ReadState m a Source #

reader_ :: Proxy# tag -> (r -> a) -> ReadState m a Source #

HasState tag r m => HasReader (tag :: k) r (ReadStatePure m) Source # 
Instance details

Defined in Capability.Reader.Internal.Strategies

Methods

local_ :: Proxy# tag -> (r -> r) -> ReadStatePure m a -> ReadStatePure m a Source #

reader_ :: Proxy# tag -> (r -> a) -> ReadStatePure m a Source #

MonadReader r m => HasReader (tag :: k) r (MonadReader m) Source # 
Instance details

Defined in Capability.Reader.Internal.Strategies

Methods

local_ :: Proxy# tag -> (r -> r) -> MonadReader m a -> MonadReader m a Source #

reader_ :: Proxy# tag -> (r -> a) -> MonadReader m a Source #

(Coercible from to, HasReader tag from m, forall x y. Coercible x y => Coercible (m x) (m y)) => HasReader (tag :: k) to (Coerce to m) Source #

Convert the environment using safe coercion.

Instance details

Defined in Capability.Reader.Internal.Strategies

Methods

local_ :: Proxy# tag -> (to -> to) -> Coerce to m a -> Coerce to m a Source #

reader_ :: Proxy# tag -> (to -> a) -> Coerce to m a Source #

(Monad m, Reifies s (Reified tag (HasReader tag r) m)) => HasSource (tag :: k) r (Reflected s (HasReader tag r) m) Source # 
Instance details

Defined in Capability.Reader.Internal.Class

Methods

await_ :: Proxy# tag -> Reflected s (HasReader tag r) m r Source #

(Monad m, Reifies s (Reified tag (HasReader tag r) m)) => HasReader (tag :: k) r (Reflected s (HasReader tag r) m) Source # 
Instance details

Defined in Capability.Reader.Internal.Class

Methods

local_ :: Proxy# tag -> (r -> r) -> Reflected s (HasReader tag r) m a -> Reflected s (HasReader tag r) m a Source #

reader_ :: Proxy# tag -> (r -> a) -> Reflected s (HasReader tag r) m a Source #

HasReader oldtag r m => HasReader (newtag :: k2) r (Rename oldtag m) Source #

Rename the tag.

Instance details

Defined in Capability.Reader.Internal.Strategies

Methods

local_ :: Proxy# newtag -> (r -> r) -> Rename oldtag m a -> Rename oldtag m a Source #

reader_ :: Proxy# newtag -> (r -> a) -> Rename oldtag m a Source #

(forall x. Coercible (m x) (t2 (t1 m) x), Monad m, HasReader tag r (t2 (t1 m))) => HasReader (tag :: k) r ((t2 :.: t1) m) Source #

Compose two accessors.

Instance details

Defined in Capability.Reader.Internal.Strategies

Methods

local_ :: Proxy# tag -> (r -> r) -> (t2 :.: t1) m a -> (t2 :.: t1) m a Source #

reader_ :: Proxy# tag -> (r -> a) -> (t2 :.: t1) m a Source #

(tag ~ pos, HasPosition' pos struct v, HasReader oldtag struct m) => HasReader (tag :: Nat) v (Pos pos oldtag m) Source #

Zoom in on the field at position pos of type v in the environment struct.

Instance details

Defined in Capability.Reader.Internal.Strategies

Methods

local_ :: Proxy# tag -> (v -> v) -> Pos pos oldtag m a -> Pos pos oldtag m a Source #

reader_ :: Proxy# tag -> (v -> a) -> Pos pos oldtag m a Source #

(tag ~ field, HasField' field record v, HasReader oldtag record m) => HasReader (tag :: Symbol) v (Field field oldtag m) Source #

Zoom in on the record field field of type v in the environment record.

Instance details

Defined in Capability.Reader.Internal.Strategies

Methods

local_ :: Proxy# tag -> (v -> v) -> Field field oldtag m a -> Field field oldtag m a Source #

reader_ :: Proxy# tag -> (v -> a) -> Field field oldtag m a Source #

data Reified (tag :: k) (HasReader tag r) m Source # 
Instance details

Defined in Capability.Reader.Internal.Class

data Reified (tag :: k) (HasReader tag r) m = ReifiedReader {}

ask :: forall tag r m. HasReader tag r m => m r Source #

ask @tag retrieves the environment of the reader capability tag.

asks :: forall tag r m a. HasReader tag r m => (r -> a) -> m a Source #

asks @tag retrieves the image by f of the environment of the reader capability tag.

asks @tag f = f <$> ask @tag

local :: forall tag r m a. HasReader tag r m => (r -> r) -> m a -> m a Source #

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.

reader :: forall tag r m a. HasReader tag r m => (r -> a) -> m a Source #

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.

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 Source #

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.

data family Reified (tag :: k) (c :: Capability) (m :: Type -> Type) Source #

Reified tag capability m

Defines the dictionary type for the methods of capability under tag in the monad m. Refer to interpret_ for an example use-case.

For example, the HasSink capability has the method yield :: a -> m (). The corresponding dictionary type is defined as follows.

>>> :{
  data instance Reified tag (HasSink tag a) m =
    ReifiedSink { _yield :: forall a. a -> m () }
  :}

Superclass dictionaries are represented as nested records. For example, the HasState capability has the superclasses HasSource and HasSink and the method state :: (s -> (a, s)) -> m a. The corresponding dictionary type is defined as follows.

>>> :{
  data instance Reified tag (HasState tag s) m =
    ReifiedState
      { _stateSource :: Reified tag (HasSource tag s) m,
        _stateSink :: Reified tag (HasSink tag s) m,
        _state :: forall a. (s -> (a, s)) -> m a
      }
  :}

Instances

Instances details
data Reified (tag :: k) (HasSink tag a) m Source # 
Instance details

Defined in Capability.Sink.Internal.Class

data Reified (tag :: k) (HasSink tag a) m = ReifiedSink {}
data Reified (tag :: k) (HasSource tag a) m Source # 
Instance details

Defined in Capability.Source.Internal.Class

data Reified (tag :: k) (HasSource tag a) m = ReifiedSource {}
data Reified (tag :: k) (HasReader tag r) m Source # 
Instance details

Defined in Capability.Reader.Internal.Class

data Reified (tag :: k) (HasReader tag r) m = ReifiedReader {}
data Reified (tag :: k) (HasState tag s) m Source # 
Instance details

Defined in Capability.State.Internal.Class

data Reified (tag :: k) (HasState tag s) m = ReifiedState {}
data Reified (tag :: k) (HasThrow tag e) m Source # 
Instance details

Defined in Capability.Error

data Reified (tag :: k) (HasThrow tag e) m = ReifiedThrow {}
data Reified (tag :: k) (HasCatch tag e) m Source # 
Instance details

Defined in Capability.Error

data Reified (tag :: k) (HasCatch tag e) m = ReifiedCatch {}
data Reified (tag :: k) (HasWriter tag w) m Source # 
Instance details

Defined in Capability.Writer

data Reified (tag :: k) (HasWriter tag w) m = ReifiedWriter {}

Functional capability

type HasReader' (tag :: k) = HasReader tag (TypeOf k tag) Source #

Type synonym using the TypeOf type family to specify HasReader constraints without having to specify the type associated to a tag.

type family TypeOf k (s :: k) :: Type Source #

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 Type 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 Type Foo = Int
    type instance TypeOf Type Bar = String

    -- Same as: foo :: HasReader Foo Int M => …
    foo :: HasReader' Foo m => …
    foo = …

Strategies

newtype MonadReader (m :: Type -> Type) (a :: Type) Source #

Derive HasSource from m's MonadReader instance.

Constructors

MonadReader (m a) 

Instances

Instances details
MonadReader r m => HasSource (tag :: k) r (MonadReader m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

await_ :: Proxy# tag -> MonadReader m r Source #

MonadReader r m => HasReader (tag :: k) r (MonadReader m) Source # 
Instance details

Defined in Capability.Reader.Internal.Strategies

Methods

local_ :: Proxy# tag -> (r -> r) -> MonadReader m a -> MonadReader m a Source #

reader_ :: Proxy# tag -> (r -> a) -> MonadReader m a Source #

Monad m => Monad (MonadReader m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

(>>=) :: MonadReader m a -> (a -> MonadReader m b) -> MonadReader m b #

(>>) :: MonadReader m a -> MonadReader m b -> MonadReader m b #

return :: a -> MonadReader m a #

Functor m => Functor (MonadReader m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

fmap :: (a -> b) -> MonadReader m a -> MonadReader m b #

(<$) :: a -> MonadReader m b -> MonadReader m a #

Applicative m => Applicative (MonadReader m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

pure :: a -> MonadReader m a #

(<*>) :: MonadReader m (a -> b) -> MonadReader m a -> MonadReader m b #

liftA2 :: (a -> b -> c) -> MonadReader m a -> MonadReader m b -> MonadReader m c #

(*>) :: MonadReader m a -> MonadReader m b -> MonadReader m b #

(<*) :: MonadReader m a -> MonadReader m b -> MonadReader m a #

MonadIO m => MonadIO (MonadReader m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

liftIO :: IO a -> MonadReader m a #

PrimMonad m => PrimMonad (MonadReader m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Associated Types

type PrimState (MonadReader m) #

Methods

primitive :: (State# (PrimState (MonadReader m)) -> (# State# (PrimState (MonadReader m)), a #)) -> MonadReader m a #

type PrimState (MonadReader m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

newtype ReadStatePure (m :: Type -> Type) (a :: Type) Source #

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.

Constructors

ReadStatePure (m a) 

Instances

Instances details
HasState tag r m => HasSource (tag :: k) r (ReadStatePure m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

await_ :: Proxy# tag -> ReadStatePure m r Source #

HasState tag r m => HasReader (tag :: k) r (ReadStatePure m) Source # 
Instance details

Defined in Capability.Reader.Internal.Strategies

Methods

local_ :: Proxy# tag -> (r -> r) -> ReadStatePure m a -> ReadStatePure m a Source #

reader_ :: Proxy# tag -> (r -> a) -> ReadStatePure m a Source #

Monad m => Monad (ReadStatePure m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

(>>=) :: ReadStatePure m a -> (a -> ReadStatePure m b) -> ReadStatePure m b #

(>>) :: ReadStatePure m a -> ReadStatePure m b -> ReadStatePure m b #

return :: a -> ReadStatePure m a #

Functor m => Functor (ReadStatePure m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

fmap :: (a -> b) -> ReadStatePure m a -> ReadStatePure m b #

(<$) :: a -> ReadStatePure m b -> ReadStatePure m a #

Applicative m => Applicative (ReadStatePure m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

pure :: a -> ReadStatePure m a #

(<*>) :: ReadStatePure m (a -> b) -> ReadStatePure m a -> ReadStatePure m b #

liftA2 :: (a -> b -> c) -> ReadStatePure m a -> ReadStatePure m b -> ReadStatePure m c #

(*>) :: ReadStatePure m a -> ReadStatePure m b -> ReadStatePure m b #

(<*) :: ReadStatePure m a -> ReadStatePure m b -> ReadStatePure m a #

newtype ReadState (m :: Type -> Type) (a :: Type) Source #

Convert a state monad into a reader monad.

Use this if the monad stack allows catching exceptions.

See ReadStatePure.

Constructors

ReadState (m a) 

Instances

Instances details
(HasState tag r m, MonadMask m) => HasSource (tag :: k) r (ReadState m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

await_ :: Proxy# tag -> ReadState m r Source #

(HasState tag r m, MonadMask m) => HasReader (tag :: k) r (ReadState m) Source # 
Instance details

Defined in Capability.Reader.Internal.Strategies

Methods

local_ :: Proxy# tag -> (r -> r) -> ReadState m a -> ReadState m a Source #

reader_ :: Proxy# tag -> (r -> a) -> ReadState m a Source #

Monad m => Monad (ReadState m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

(>>=) :: ReadState m a -> (a -> ReadState m b) -> ReadState m b #

(>>) :: ReadState m a -> ReadState m b -> ReadState m b #

return :: a -> ReadState m a #

Functor m => Functor (ReadState m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

fmap :: (a -> b) -> ReadState m a -> ReadState m b #

(<$) :: a -> ReadState m b -> ReadState m a #

Applicative m => Applicative (ReadState m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

pure :: a -> ReadState m a #

(<*>) :: ReadState m (a -> b) -> ReadState m a -> ReadState m b #

liftA2 :: (a -> b -> c) -> ReadState m a -> ReadState m b -> ReadState m c #

(*>) :: ReadState m a -> ReadState m b -> ReadState m b #

(<*) :: ReadState m a -> ReadState m b -> ReadState m a #

MonadIO m => MonadIO (ReadState m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

liftIO :: IO a -> ReadState m a #

PrimMonad m => PrimMonad (ReadState m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Associated Types

type PrimState (ReadState m) #

Methods

primitive :: (State# (PrimState (ReadState m)) -> (# State# (PrimState (ReadState m)), a #)) -> ReadState m a #

type PrimState (ReadState m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Modifiers