[Haskell-cafe] Stateful iteratees

Maciej Marcin Piechotka uzytkownik2 at gmail.com
Sat Apr 9 00:49:39 CEST 2011


On Thu, 2011-04-07 at 19:04 +0200, Ertugrul Soeylemez wrote:
> Hello fellow Haskellers,
> 
> I'm trying to solve a very practical problem:  I need a stateful
> iteratee monad transformer.  Explicit state passing is very inconvenient
> and would destroy the elegance of my library.
> 
> There are two approaches to this:
> 
>   1. type MyT a m = Iteratee a (StateT MyConfig m)
>   2. type MyT a m = StateT MyConfig (Iteratee a m)
> 
> Both work well except in two very specific corner cases:
> 
>   - I need to convert the transformer to 'Iteratee a m', i.e. remove the
>     state layer.  This is obviously trivial with the second variant, but
>     seems very difficult with the first one, if it's possible at all.
> 
>   - I need to use control structures of Iteratee like catchError.  This
>     is obviously trivial with the first variant, but very inconvenient
>     with the second, because I would need to reinvent many wheels.
> 
> Does someone know a cleaner, more elegant solution?  Encapsulating the
> state in the iteratee's input type is not an option.
> 
> Many thanks in advance.

The first thing that come to my mind.

runWithState :: Iteratee a (StateT s m) b -> s -> Iteratee a m (b, s)
runWithState i s = do
    let onDone v st = return (Right (v, st))
        onCont c err = return (Left (c, err))
    (i', s') <- runStateT (runIter i onDone onCont) s
    case i' of
      Left (c, err) -> icont (\str -> runWithState (c str) s') err
      Right (v, st) -> idone (v, s') st

I believe it is equivalent to:

runWithState :: Iteratee a (StateT s m) b -> s -> Iteratee a m (b, s)
runWithState i s = do
    let onDone v st = do
            s' <- get
            return (idone (v, s') st)
        onCont c err = do
            s' <- get
            return (icont (\str -> runWithState (c str) s') err)
    joinIM $ evalStateT (runIter i onDone onCont) s

I haven't tested but it compiles so it should work.







More information about the Haskell-Cafe mailing list