haskellmonadsstate-monad

State Monad then (>>)


I would like to know the definition of >> for the Haskell state monad.

By my guess it pass one state to another:

(>>) :: State s a -> State s b -> State s b
State a >> State b = State $ \x -> b $ snd ( a x )

or

State a >> State b = State $ b . snd . a

Is this correct?


Solution

  • You're pretty much right. >> is actually more general than you suggest, but you can certainly use it with the type signature you indicate. If you're using State from its usual home, Control.Monad.Trans.State.Strict, or its home away from home, Control.Monad.State.Strict, State is actually just a type synonym:

    type State s = StateT s Identity
    

    where Identity is from Data.Functor.Identity and defined

    newtype Identity x = Identity x
    

    and StateT is defined

    newtype StateT s m a = StateT {runStateT :: s -> m (a, s)}
    

    So State s a is just a newtype wrapper around

    s -> Identity (a, s)
    

    This is essentially the same as the definition you imagine, but it allows State s to be compatible with the monad transformer StateT s, which is used to add state to arbitrary Monads.

    instance Monad m => Monad (StateT s m) where
      return a = StateT $ \s -> return (a, s)
      StateT g >>= f = StateT $ \s -> g s >>= \(r,s') -> runStateT (f r) s'
    

    So

      StateT g >> StateT h = StateT $ \s -> g s >>= \(_,s') -> h s'
    
                           = StateT $ \s -> h $ snd $ runIdentity (g s)
                           = StateT $ h . snd . runIdentity . g
    

    Irrelevant side note

    The definition of StateT annoys me, because in my opinion it puts the elements of the pairs in the wrong order. Why wrong? Because mapping over (a, s) changes s while leaving a alone, and that is not what happens when mapping over a state transformer. End result: poor intuition.