[Haskell-cafe] Lifting an enumerator
John Lenz
jlenz2 at uic.edu
Wed Aug 24 16:19:03 CEST 2011
On 08/24/2011 09:02 AM, Michael Snoyman wrote:
> Hi all,
>
> Max asked earlier[1] how to create a new instance of a class in
> Persistent using a monad transformer. Without getting into the
> specific details of persistent, I wanted to pose a question based on a
> much more general question: how can we lift the inner monad of an
> enumerator? We can easily do so for an Iteratee[2], but there is
> nothing to allow it for an Enumerator.
I faced the same problem a few weeks back, but for ReaderT.
I tried for a while to get it working for all transformers, but couldn't
get it to work. After spending time with this a few weeks ago, I think
perhaps you could write
liftEnum :: (Monad m, MonadTrans t, MonadCont m) => Enumerator a m b -> Enumerator a (t m) b
That is, use callCC to return the step from the inner iteratee to be able to execute the
step in the correct monad. But I didn't take the time to get it to work,
since I got the ReaderT working.
In any case, here is what I wrote for ReaderT.
John
newtype MemcacheBackend m a = MemcacheBackend { unMemBackend :: ReaderT MemcacheConnection m a }
deriving (Monad, MonadIO, MonadTrans, Functor, Applicative, Alternative,
MonadPlus, MonadCatchIO, MonadControlIO)
lower :: Monad m => MemcacheConnection -> Iteratee a (MemcacheBackend m) b -> Iteratee a m b
lower c i = Iteratee $ do step <- runReaderT (unMemBackend $ runIteratee i) c
case step of
(Error ex) -> return $ Error ex
(Yield b s) -> return $ Yield b s
(Continue f) -> return $ Continue $ lower c . f
liftEnum :: (Monad m) => Enumerator a m b -> Enumerator a (MemcacheBackend m) b
liftEnum e (Yield b s) = liftTrans $ e $ Yield b s
liftEnum e (Error err) = liftTrans $ e $ Error err
liftEnum e (Continue f) = Iteratee $ do
r <- MemcacheBackend ask
step <- lift $ runIteratee $ e $ Continue $ lower r . f
case step of
(Yield b s) -> return $ Yield b s
(Error err) -> return $ Error err
(Continue f') -> return $ Continue $ \x -> liftTrans $ f' x
More information about the Haskell-Cafe
mailing list