Maciej Marcin Piechotka <[email protected]> wrote:

> > Does someone know a cleaner, more elegant solution?  Encapsulating the
> > state in the iteratee's input type is not an option.
>
> 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

Thanks for the code.  It might come in handy, but for the current
implementation I decided not to use this approach, but instead to
generalize over 'm', which gives me better composability, for example:

  MailMonad m => Iteratee SmtpResponse m ()

Library users can write their own monads and make them instances of
MailMonad, which is very easy, because there is only one function to
implement.  This seems to solve my original problem.


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

I loved that statement -- specifically because it's not far-fetched in
Haskell.  You wouldn't dare to write anything like that in any of the
more commonly used languages. =)


Greets,
Ertugrul


-- 
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://ertes.de/



_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to