title: State monads: Transitioning from one state type to another
body: <p>Let's say we have a stack of monads with a state monad transformer as the outer most transformer like this one:</p>
  
  <pre><code>-- | SEWT: Composition of State . Except . Writer monad transformers in that
  -- order where Writer is the innermost transformer.
  -- the form of the computation is: s -&gt; (Either e (a, s), w)
  newtype SEWT s e w m a = SEWT {
      _runSEWT :: StateT s (ExceptT e (WriterT w m)) a }
      deriving (Functor, Applicative, Monad,
                MonadState s, MonadError e, MonadWriter w)
  
  -- | 'runSEWT': runs a 'SEWT' computation given an initial state.
  runSEWT :: SEWT s e w m a -&gt; s -&gt; m (Either e (a, s), w)
  runSEWT ev e = runWriterT $ runExceptT $ runStateT (_runSEWT ev) e
  </code></pre>
  
  <p>We then want to do, in some form: <code>SEWT s e w m a -&gt; s -&gt; SEWT t e w m a</code>.
  This is of course not possible using <code>(&gt;&gt;=)</code> or a <code>do</code> block since a state monad with <code>s</code> as state is not the same monad as one with <code>t</code>.</p>
  
  <p>I can then conjure up something like this:</p>
  
  <pre><code>-- | 'sewtTransition': transitions between one 'SEWT' computation with state s,
  -- to another with state s. The current state and result of the given
  -- computation is given to a mapping function that must produce the next
  -- computation. The initial state must also be passed as the last parameter.
  transitionState :: (Monad m, Monoid w) =&gt; ((a, s) -&gt; SEWT t e w m a)
                  -&gt; m (SEWT s e w m a) -&gt; s -&gt; m (SEWT t e w m a)
  transitionState _trans _comp _init = do
      (res, logs) &lt;- _comp &gt;&gt;= flip runSEWT _init
      return $ do tell logs 
                  case res of Left  fail -&gt; throwError fail
                              Right succ -&gt; _trans succ
  
  -- 'withState': behaves like 'transitionState' but ignores the state of
  -- the first computation.
  withState :: (Monad m, Monoid w)
            =&gt; m (SEWT s e w m a) -&gt; s -&gt; m (SEWT t e w m a)
  withState = transitionState $ return . fst
  </code></pre>
  
  <p>But is there perhaps a more elegant and general way to move from one state type to another?</p>
  
  <p>I'm interested both in solutions where the second computation is not dependent on the final state (only the result) of the first computation, and one where it is.</p>
  
  <p>Edit1: Improved transition functions:</p>
  
  <pre><code>transSEWT :: Functor m =&gt; (((a, y), x) -&gt; (a, y)) -&gt; SEWT x e w m a -&gt; x -&gt; SEWT y e w m a
  transSEWT f x_c x_i = SEWT $ StateT $ \y_i -&gt; ExceptT . WriterT $
      first ((\(a, x_f) -&gt; f ((a, y_i), x_f)) &lt;$&gt;) &lt;$&gt; runSEWT x_c x_i
  
  changeSEWT :: Functor m =&gt; SEWT x e w m a -&gt; x -&gt; SEWT y e w m a
  changeSEWT = transSEWT fst
  
  transS :: Monad m =&gt; (((a, y), x) -&gt; (a, y)) -&gt; StateT x m a -&gt; x -&gt; StateT y m a
  transS f x_c x_i = StateT $ \y_i -&gt; do (a, x_f) &lt;- runStateT x_c x_i
                                         return $ f ((a, y_i), x_f)
  
  changeS :: Monad m =&gt; StateT x m a -&gt; x -&gt; StateT y m a
  changeS = transS fst
  </code></pre>