On Fri, Apr 23, 2010 at 3:46 PM, Dan Doel <dan.doel@gmail.com> wrote:
On Friday 23 April 2010 1:39:36 pm Anders Kaseorg wrote:
On Fri, 23 Apr 2010, Tyson Whitehead wrote:
Are you then saying that liftIO should be able to be defined via morphIO? I would be curious to see that as, after a bit of trying, I still can't see how to. Specifically, I can't capture the results of the desired IO operation.
Yes, just like lift is defined via morph:
liftIO' :: (MonadMorphIO m) => IO a -> m a liftIO' m = morphIO $ \down -> m >>= down . return
main = runContT (runReaderT main' ()) return main' = do liftIO' $ putStrLn "What is your name?" name <- liftIO' $ getLine liftIO' $ putStrLn $ "Hello " ++ name
Can lift really be defined from morph, though? Given just:
class MonadTrans t where morph :: Monad m => (forall b. (t m a -> m b) -> m b) -> t m a
trying to define:
lift :: (Monad m, MonadTrans t) => m a -> t m a lift m = morph (\k -> m >>= k . return)
yields an error. Monad m and MonadTrans t do not imply Monad (t m), which is what that definition requires.
This works for me: lift :: (MonadTrans t, Monad m, Monad (t m)) => m a -> t m a lift m = morph (\d -> m >>= d . return) Ideally, we'd be able to give (forall m. Monad m => Monad (t m)) as a requirement of MonadTrans. As it happens, my own monad library simulates that with an extra class. class MonadTrans t where return1 :: Monad m => a -> t m a bind1 :: Monad m => t m a -> (a -> t m b) -> t m b class MonadTrans t => MonadLift t where lift :: Monad m => m a -> t m a This is pretty straightforward to extend: class MonadLift t => MonadMorph t where morph :: Monad m => (forall b. (t m a -> m b) -> m b) -> t m a lift_ :: (MonadMorph t, Monad m) => m a -> t m a lift_ m = morph (\d -> m >>= d . return1) The question I would ask is whether morph can be sensibly defined for the backtracking monad. It's a good example of a class of monads which are more complicated than the usual state and exceptions stuff, but not as powerful or complex as ContT. -- Dave Menendez <dave@zednenem.com> <http://www.eyrie.org/~zednenem/>