| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
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
- class Monad m => HasState (tag :: k) (s :: *) (m :: * -> *) | tag m -> s where
- get :: forall tag s m. HasState tag s m => m s
- put :: forall tag s m. HasState tag s m => s -> m ()
- state :: forall tag s m a. HasState tag s m => (s -> (a, s)) -> m a
- modify :: forall tag s m. HasState tag s m => (s -> s) -> m ()
- modify' :: forall tag s m. HasState tag s m => (s -> s) -> m ()
- gets :: forall tag s m a. HasState tag s m => (s -> a) -> m a
- 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
- newtype MonadState (m :: * -> *) (a :: *) = MonadState (m a)
- newtype ReaderIORef m a = ReaderIORef (m a)
- newtype ReaderRef m (a :: *) = ReaderRef (m a)
- module Capability.Accessors
Interface
class Monad 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
get_ :: Proxy# tag -> m s 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 get.
See get for more documentation.
Instances
| (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. |
| MonadState s m => HasState (tag :: k) s (MonadState m) Source # | |
Defined in Capability.State.Internal.Strategies Methods get_ :: Proxy# tag -> MonadState m s Source # put_ :: Proxy# tag -> s -> MonadState m () Source # state_ :: Proxy# tag -> (s -> (a, s)) -> MonadState m a Source # | |
| (MutableRef ref, RefElement ref ~ s, HasReader tag ref m, PrimMonad m, PrimState m ~ MCState ref) => HasState (tag :: k) s (ReaderRef m) 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. |
| (HasReader tag (IORef s) m, MonadIO m) => HasState (tag :: k) s (ReaderIORef m) Source # | |
Defined in Capability.State.Internal.Strategies Methods get_ :: Proxy# tag -> ReaderIORef m s Source # put_ :: Proxy# tag -> s -> ReaderIORef m () Source # state_ :: Proxy# tag -> (s -> (a, s)) -> ReaderIORef m a Source # | |
| HasState oldtag s m => HasState (newtag :: k1) s (Rename oldtag m) Source # | Rename the tag. |
| (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. |
| (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 |
| (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 |
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 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 Source #
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.
Strategies
newtype MonadState (m :: * -> *) (a :: *) Source #
Derive HasState from m's
MonadState instance.
Constructors
| MonadState (m a) |
Instances
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
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, HasReader tag ref m, PrimMonad m, PrimState m ~ MCState ref) => HasState (tag :: k) s (ReaderRef m) Source # | |
| Monad m => Monad (ReaderRef m) Source # | |
| Functor m => Functor (ReaderRef m) Source # | |
| Applicative m => Applicative (ReaderRef m) Source # | |
Defined in Capability.State.Internal.Strategies | |
| MonadIO m => MonadIO (ReaderRef m) Source # | |
Defined in Capability.State.Internal.Strategies | |
| PrimMonad m => PrimMonad (ReaderRef m) Source # | |
| type PrimState (ReaderRef m) Source # | |
Defined in Capability.State.Internal.Strategies | |
Modifiers
module Capability.Accessors