Richard Silverman wrote:
I'm puzzled by something. Suppose I have some code that does lots of IO,
and also occasionally refers to some global state. No problem, use
ReaderT for the state, combining with the IO monad. Except... since IO
is on the bottom, simple uses of do-notation such as "foo <- ask" work
in the Reader monad, and to access the IO monad, I need to lift, e.g.
(bar <- liftIO getLine). If my code does lots of IO, this is *very* ugly
-- the code is littered with lift functions! Is there no cleaner way to
do this?
Not that I know of. However, you can usually group IO-statements
together in one bigger block:
blah = do
foo <- ask
biz <- liftIO $ do
meep
bop foo
bleep foo
zap biz
etc.
And if there is a limited number of specific functions you need to lift
often, you can write generalised MonadIO-based versions of these so that
you can call them directly from the monad transformer:
getLine :: MonadIO m => m String
getLine = liftIO SystemIO.getLine
Assuming an appropriate MonadIO instance of ReaderT, of course.
Does that help?
Martijn.
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe