
Dear collegues, I use Iteratee with Monad Transformer stack in this way: type MyMonad a b = Iteratee a (StateT StateType IO) b I've wrote some Enumeratees using this type. Then I want to compose it with standard enumerator like Data.Enumerator.Binary.enumFile. But enumFile use IO monad instead of MonadIO class. I didn't see (maybe I'm blind...) a way to compose my Enumeratees with enumFile. How I can do that? Is it possible to change enumFile to using MonadIO class? Best regards, Dmitry

On 4/1/11 3:59 PM, Dmitry Olshansky wrote:
But enumFile use IO monad instead of MonadIO class. [...] Is it possible to change enumFile to using MonadIO class?
Unless its changed significantly since I looked at it last (which it may well have), it's not possible. The problem is that what we'd really need is lowerIO :: m a -> IO a for the m in question; liftIO goes the wrong way. Of course, getting a lowerIO with the right semantics will be tricky for most monads. -- Live well, ~wren

On 1 April 2011 21:59, Dmitry Olshansky
Is it possible to change enumFile to using MonadIO class?
No because it uses the control operation Control.Exception.finally :: IO a -> IO b -> IO a internally. You can't lift control operations with liftIO :: MonadIO m => IO a -> m a. However if you are able to define a MonadTransControl and MonadControlIO instance (from the monad-control package[1]) for Iteratee and use Control.Exception.Control.finally instead of the regular finally, you can use your MyMonad with the modified enumFile. Good luck, Bas [1] http://hackage.haskell.org/package/monad-control

Very interesting, thanks.
I didn't feel your classes yet... Do you think that provide these instances
for Iteratee is possible?
2011/4/2 Bas van Dijk
On 1 April 2011 21:59, Dmitry Olshansky
wrote: Is it possible to change enumFile to using MonadIO class?
No because it uses the control operation Control.Exception.finally :: IO a -> IO b -> IO a internally. You can't lift control operations with liftIO :: MonadIO m => IO a -> m a.
However if you are able to define a MonadTransControl and MonadControlIO instance (from the monad-control package[1]) for Iteratee and use Control.Exception.Control.finally instead of the regular finally, you can use your MyMonad with the modified enumFile.
Good luck,
Bas

Bas van Dijk
On 1 April 2011 21:59, Dmitry Olshansky
wrote: Is it possible to change enumFile to using MonadIO class?
No because it uses the control operation Control.Exception.finally :: IO a -> IO b -> IO a internally. You can't lift control operations with liftIO :: MonadIO m => IO a -> m a.
However if you are able to define a MonadTransControl and MonadControlIO instance (from the monad-control package[1]) for Iteratee and use Control.Exception.Control.finally instead of the regular finally, you can use your MyMonad with the modified enumFile.
I don't think that's possible, because Iteratee is based on CPS. I think, so far nobody has come up with an instance definition for monad-peel or monad-control for CPS-based monads like ContT or Iteratee. However, it is easy to write an own handle enumerator, which uses monad-peel or monad-control exception handling to convert errors to iteratee exceptions. On the other hand, as has been noted, there is enumHandle, which does that by itself. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/

Ertugrul,
thanks for information. I've found several decisions for my real problem
(using enumHandle and some more special decision).
But I'll be have in mind about monad-control.
2011/4/3 Ertugrul Soeylemez
Bas van Dijk
wrote: On 1 April 2011 21:59, Dmitry Olshansky
wrote: Is it possible to change enumFile to using MonadIO class?
No because it uses the control operation Control.Exception.finally :: IO a -> IO b -> IO a internally. You can't lift control operations with liftIO :: MonadIO m => IO a -> m a.
However if you are able to define a MonadTransControl and MonadControlIO instance (from the monad-control package[1]) for Iteratee and use Control.Exception.Control.finally instead of the regular finally, you can use your MyMonad with the modified enumFile.
I don't think that's possible, because Iteratee is based on CPS. I think, so far nobody has come up with an instance definition for monad-peel or monad-control for CPS-based monads like ContT or Iteratee.
However, it is easy to write an own handle enumerator, which uses monad-peel or monad-control exception handling to convert errors to iteratee exceptions. On the other hand, as has been noted, there is enumHandle, which does that by itself.
Greets, Ertugrul
-- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Use enumHandle. enumFile deals with the common case of "read from the filesystem in IO". It can't deal with general MonadIO monads because there'd be no guarantee that the handle would actually be closed (eg, an ErrorT IO might never run the cleanup). If you need a special monad, do something like: withBinaryFile $ \h -> runMyMonad (run_ (enumHandle h $$ myIter))
participants (5)
-
Bas van Dijk
-
Dmitry Olshansky
-
Ertugrul Soeylemez
-
John Millikin
-
wren ng thornton