nobody
nobody

Reputation: 414

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?

Upvotes: 1

Views: 142

Answers (2)

dfeuer
dfeuer

Reputation: 48631

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.

Upvotes: 4

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477759

I think this Wikipedia page gives a definition for (>>=) for the State monad:

m >>= f = \r -> let (x, s) = m r in (f x) s

Since (>>) is implemented in terms of (>>=) as follows:

m >> k = m >>= \_ -> k

one can derive the definition for (>>) for the state monad:

m >> k = \r -> let (x, s) = m r in ((\_ -> k) x) s

or when removing the noise:

m >> k = \r -> let (x, s) = m r in k s

Now since x does not play a part in the in clause, you can indeed use snd to get s, which can thus be rewritten to:

m >> k = \r -> k $ snd m r

Upvotes: 2

Related Questions