capability-0.1.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

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.

put_ :: Proxy# tag -> s -> m () 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 put. See put for more documentation.

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
(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

get_ :: Proxy# tag -> Lift (t m) s Source #

put_ :: Proxy# tag -> s -> Lift (t m) () Source #

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

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 # 
Instance details

Defined in Capability.State.Internal.Strategies

Methods

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

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

state_ :: Proxy# tag -> (s -> (a, s)) -> ReaderRef 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

get_ :: Proxy# tag -> Coerce to m to Source #

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

state_ :: Proxy# tag -> (to -> (a, to)) -> Coerce to 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

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.

Instance details

Defined in Capability.State.Internal.Strategies

Methods

get_ :: Proxy# newtag -> Rename oldtag m s Source #

put_ :: Proxy# newtag -> s -> Rename oldtag m () Source #

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

get_ :: Proxy# tag -> (t2 :.: t1) m s Source #

put_ :: Proxy# tag -> s -> (t2 :.: t1) m () Source #

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

get_ :: Proxy# tag -> Pos pos oldtag m v Source #

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

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

get_ :: Proxy# tag -> Field field oldtag m v Source #

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

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 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
MonadState s m => HasState (tag :: k) s (MonadState m) Source # 
Instance details

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 #

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

Defined in Capability.State.Internal.Strategies

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

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

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

Methods

liftIO :: IO a -> MonadState m a #

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

Defined in Capability.State.Internal.Strategies

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

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
(HasReader tag (IORef s) m, MonadIO m) => HasState (tag :: k) s (ReaderIORef m) Source # 
Instance details

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 #

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

Defined in Capability.State.Internal.Strategies

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

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

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, 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

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

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

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

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

Defined in Capability.State.Internal.Strategies

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

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

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

Methods

liftIO :: IO a -> ReaderRef m a #

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

Defined in Capability.State.Internal.Strategies

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

Modifiers