| Copyright | (C) 2016-2026 David M. Johnson |
|---|---|
| License | BSD3-style (see the file LICENSE) |
| Maintainer | David M. Johnson <code@dmj.io> |
| Stability | experimental |
| Portability | non-portable |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
Miso.State
Description
Overview
Miso.State re-exports the RWS combinators that are
most useful inside an Effect handler. Because
Effect is an RWS monad, the full
MonadState,
MonadReader, and
MonadWriter interfaces are available
without importing mtl directly.
This module is re-exported in its entirety by Miso, so most applications do not need to import it explicitly.
Quick start
import Miso -- re-exports Miso.State -- or import Miso.State -- explicit import data Model = Model { _count :: Int } deriving (Eq) data Action = Increment | Decrement | Reset | Log update :: Action ->Effectp props Model Action update Increment =modify(\m -> m { _count = _count m + 1 }) update Decrement =modify'(\m -> m { _count = _count m - 1 }) update Reset =put(Model 0) update Log = do n <-gets_countio_(consoleLog (msn))
When using Miso.Lens or Miso.Lens.TH, the lens update operators
(, .=, +=, …) are built directly on %=modify, so
explicit calls to modify / put are rarely needed.
Exported combinators
- Reader (component metadata):
ask,asks - State (model):
get,gets,modify,modify',put - Writer (schedule IO):
tell - IO lift:
liftIO
See also
- Miso.Effect —
Effect,io,io_,sync - Miso.Lens — lens operators that wrap
modify - Miso.Lens.TH — Template Haskell lens generation
Synopsis
- ask :: MonadReader r m => m r
- asks :: MonadReader r m => (r -> a) -> m a
- modify :: MonadState s m => (s -> s) -> m ()
- modify' :: MonadState s m => (s -> s) -> m ()
- get :: MonadState s m => m s
- gets :: MonadState s m => (s -> a) -> m a
- put :: MonadState s m => s -> m ()
- tell :: MonadWriter w m => w -> m ()
- liftIO :: MonadIO m => IO a -> m a
Documentation
ask :: MonadReader r m => m r #
Retrieves the monad environment.
Arguments
| :: MonadReader r m | |
| => (r -> a) | The selector function to apply to the environment. |
| -> m a |
Retrieves a function of the current environment.
modify :: MonadState s m => (s -> s) -> m () #
Monadic state transformer.
Maps an old state to a new state inside a state monad. The old state is thrown away.
Main> :t modify ((+1) :: Int -> Int)
modify (...) :: (MonadState Int a) => a ()This says that modify (+1) acts over any
Monad that is a member of the MonadState class,
with an Int state.
modify' :: MonadState s m => (s -> s) -> m () #
A variant of modify in which the computation is strict in the
new state.
Since: mtl-2.2
get :: MonadState s m => m s #
Return the state from the internals of the monad.
gets :: MonadState s m => (s -> a) -> m a #
Gets specific component of the state, using a projection function supplied.
put :: MonadState s m => s -> m () #
Replace the state inside the monad.
tell :: MonadWriter w m => w -> m () #
is an action that produces the output tell ww.
liftIO :: MonadIO m => IO a -> m a #
Lift a computation from the IO monad.
This allows us to run IO computations in any monadic stack, so long as it supports these kinds of operations
(i.e. IO is the base monad for the stack).
Example
import Control.Monad.Trans.State -- from the "transformers" library printState :: Show s => StateT s IO () printState = do state <- get liftIO $ print state
Had we omitted , we would have ended up with this error:liftIO
• Couldn't match type ‘IO’ with ‘StateT s IO’ Expected type: StateT s IO () Actual type: IO ()
The important part here is the mismatch between StateT s IO () and .IO ()
Luckily, we know of a function that takes an and returns an IO a(m a): ,
enabling us to run the program and see the expected results:liftIO
> evalStateT printState "hello" "hello" > evalStateT printState 3 3