capability-0.3.0.0: Extensional capabilities and deriving combinators

Safe HaskellNone
LanguageHaskell2010

Capability.State

Contents

Description

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.

Synopsis

Relational capability

class (Monad m, HasSource tag s m, HasSink tag s m) => HasState (tag :: k) (s :: *) (m :: * -> *) | tag m -> s where Source #

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

Methods

state_ :: Proxy# tag -> (s -> (a, s)) -> m a Source #

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.

Instances
(MutableRef ref, RefElement ref ~ s, HasReader tag ref m, PrimMonad m, PrimState m ~ MCState ref) => HasState (tag :: k) s (ReaderRef m) Source # 
Instance details

Defined in Capability.State.Internal.Strategies

Methods

state_ :: Proxy# tag -> (s -> (a, s)) -> ReaderRef m a Source #

(HasState tag s m, MonadTrans t, Monad (t m)) => HasState (tag :: k) s (Lift (t m)) Source #

Lift one layer in a monad transformer stack.

Instance details

Defined in Capability.State.Internal.Strategies

Methods

state_ :: Proxy# tag -> (s -> (a, s)) -> Lift (t m) a Source #

MonadState s m => HasState (tag :: k) s (MonadState m) Source # 
Instance details

Defined in Capability.State.Internal.Strategies

Methods

state_ :: Proxy# tag -> (s -> (a, s)) -> MonadState m a Source #

(HasReader tag (IORef s) m, MonadIO m) => HasState (tag :: k) s (ReaderIORef m) Source # 
Instance details

Defined in Capability.State.Internal.Strategies

Methods

state_ :: Proxy# tag -> (s -> (a, s)) -> ReaderIORef m a Source #

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

Convert the state using safe coercion.

Instance details

Defined in Capability.State.Internal.Strategies

Methods

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

HasState oldtag s m => HasState (newtag :: k1) s (Rename oldtag m) Source #

Rename the tag.

Instance details

Defined in Capability.State.Internal.Strategies

Methods

state_ :: Proxy# newtag -> (s -> (a, s)) -> Rename oldtag m a Source #

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

Compose two accessors.

Instance details

Defined in Capability.State.Internal.Strategies

Methods

state_ :: Proxy# tag -> (s -> (a, s)) -> (t2 :.: t1) m a Source #

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

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

Instance details

Defined in Capability.State.Internal.Strategies

Methods

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

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

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

Instance details

Defined in Capability.State.Internal.Strategies

Methods

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

get :: forall tag s m. HasState tag s m => m s Source #

get @tag retrieve the current state of the state capability tag.

put :: forall tag s m. HasState tag s m => s -> m () Source #

put @tag s replace the current state of the state capability tag with s.

state :: forall tag s m a. HasState tag s m => (s -> (a, s)) -> m a Source #

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.

modify :: forall tag s m. HasState tag s m => (s -> s) -> m () Source #

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

Same as modify but strict in the new state.

gets :: forall tag s m a. HasState tag s m => (s -> a) -> m a Source #

gets @tag f retrieves the image, by f of the current state of the state capability tag.

gets @tag f = f <$> get @tag

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

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.

Functional capability

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

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

type family TypeOf k (s :: k) :: * 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 * 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 = …

Strategies

newtype MonadState (m :: * -> *) (a :: *) Source #

Derive HasState from m's MonadState instance.

Constructors

MonadState (m a) 
Instances
MonadState s m => HasSink (tag :: k) s (MonadState m) Source # 
Instance details

Defined in Capability.Sink.Internal.Strategies

Methods

yield_ :: Proxy# tag -> s -> MonadState m () Source #

MonadState s m => HasSource (tag :: k) s (MonadState m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

await_ :: Proxy# tag -> MonadState m s Source #

MonadState s m => HasState (tag :: k) s (MonadState m) Source # 
Instance details

Defined in Capability.State.Internal.Strategies

Methods

state_ :: Proxy# tag -> (s -> (a, s)) -> MonadState m a Source #

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

Defined in Capability.State.Internal.Strategies.Common

Methods

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

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

return :: a -> MonadState m a #

fail :: String -> MonadState m a #

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

Defined in Capability.State.Internal.Strategies.Common

Methods

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

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

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

Defined in Capability.State.Internal.Strategies.Common

Methods

pure :: a -> MonadState m a #

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

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

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

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

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

Defined in Capability.State.Internal.Strategies.Common

Methods

liftIO :: IO a -> MonadState m a #

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

Defined in Capability.State.Internal.Strategies.Common

Associated Types

type PrimState (MonadState m) :: Type #

Methods

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

type PrimState (MonadState m) Source # 
Instance details

Defined in Capability.State.Internal.Strategies.Common

newtype ReaderIORef m a Source #

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.

Constructors

ReaderIORef (m a) 
Instances
(HasSource tag (IORef s) m, MonadIO m) => HasSink (tag :: k) s (ReaderIORef m) Source # 
Instance details

Defined in Capability.Sink.Internal.Strategies

Methods

yield_ :: Proxy# tag -> s -> ReaderIORef m () Source #

(HasSource tag (IORef s) m, MonadIO m) => HasSource (tag :: k) s (ReaderIORef m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

await_ :: Proxy# tag -> ReaderIORef m s Source #

(HasReader tag (IORef s) m, MonadIO m) => HasState (tag :: k) s (ReaderIORef m) Source # 
Instance details

Defined in Capability.State.Internal.Strategies

Methods

state_ :: Proxy# tag -> (s -> (a, s)) -> ReaderIORef m a Source #

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

Defined in Capability.State.Internal.Strategies.Common

Methods

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

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

return :: a -> ReaderIORef m a #

fail :: String -> ReaderIORef m a #

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

Defined in Capability.State.Internal.Strategies.Common

Methods

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

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

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

Defined in Capability.State.Internal.Strategies.Common

Methods

pure :: a -> ReaderIORef m a #

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

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

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

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

newtype ReaderRef m (a :: *) Source #

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.

Constructors

ReaderRef (m a) 
Instances
(MutableRef ref, RefElement ref ~ s, HasSource tag ref m, PrimMonad m, PrimState m ~ MCState ref) => HasSink (tag :: k) s (ReaderRef m) Source # 
Instance details

Defined in Capability.Sink.Internal.Strategies

Methods

yield_ :: Proxy# tag -> s -> ReaderRef m () Source #

(MutableRef ref, RefElement ref ~ s, HasSource tag ref m, PrimMonad m, PrimState m ~ MCState ref) => HasSource (tag :: k) s (ReaderRef m) Source # 
Instance details

Defined in Capability.Source.Internal.Strategies

Methods

await_ :: Proxy# tag -> ReaderRef m s Source #

(MutableRef ref, RefElement ref ~ s, HasReader tag ref m, PrimMonad m, PrimState m ~ MCState ref) => HasState (tag :: k) s (ReaderRef m) Source # 
Instance details

Defined in Capability.State.Internal.Strategies

Methods

state_ :: Proxy# tag -> (s -> (a, s)) -> ReaderRef m a Source #

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

Defined in Capability.State.Internal.Strategies.Common

Methods

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

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

return :: a -> ReaderRef m a #

fail :: String -> ReaderRef m a #

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

Defined in Capability.State.Internal.Strategies.Common

Methods

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

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

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

Defined in Capability.State.Internal.Strategies.Common

Methods

pure :: a -> ReaderRef m a #

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

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

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

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

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

Defined in Capability.State.Internal.Strategies.Common

Methods

liftIO :: IO a -> ReaderRef m a #

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

Defined in Capability.State.Internal.Strategies.Common

Associated Types

type PrimState (ReaderRef m) :: Type #

Methods

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

type PrimState (ReaderRef m) Source # 
Instance details

Defined in Capability.State.Internal.Strategies.Common

Modifiers