Suppose that in a Haskell program I have some data whose type is something like:
IO [ IO (Int, String, Int) ], orIO [ (Int, String, IO Int) ], or[ (Int, String, IO Int) ]
but I have pure functions that should operate on [ (Int, String, Int) ]. It seems that I’d have to clumsily remove the inside values from the IO monad, until I got something like IO [ (Int, string, Int) ] and then (from inside the IO monad) apply the pure functions. There is no easy pre-defined way to do this, I suppose? Something that would lift a whole data structure into a monad, turning all inside types into pure types? (That would be very convenient!)
You could use the
liftM*function from the Control.Monad module, or theliftA*functions for applicatives.liftMallows you to lift a pure function to work inside a Monad, e.g.:This way you don’t have to manually write things like “
s >>= \x -> return (reverse x)” everywhere.Although, this won’t help you with your
[(String, Int, IO Int)]example, if the pure function you have deals with a[(String, Int, Int)]. Since the third element in the tuple really isn’t anInt.In that case I’d suggest to first write a function
[(String, Int, IO Int)] -> IO [(String, Int, Int)]and that apply the lifted pure function.This is the most general function I could come up with to do this:
You can call it like so:
This function will only work if you have a single monad that’s somewhere deep in a type. If you have multiple, I think you should really be thinking about the type your working in with and see if you can’t make it simpler.