| 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