
jianqiuchi@gmail.com wrote:
I just want to get something from IO monad and wrap it with some other monad. Is there anyway to do that? Thanks.
You've got quite a "just" there. This is conceptually impossible, because it does not make sense. There is no "some other monad", because every monad has a precise, significant meaning and in general you cannot just cast values from one type to another. If conversion is possible, there needs to be a specific conversion function, called a natural transformation, which knows the semantics of both monads. For all 'a' and 'm', it is in general possible to convert values of type 'IO a' to 'MonadIO m => m a'. The natural transformation for that is called liftIO. What you can try to do is to find a transforming variant of whatever monad you are working in. So instead of MyMonad use MyMonadT IO. It is a common wrong interpretation that you want to "get out of" the IO monad, what technically means: You want to convert IO Something to just Something. There is indeed a combinator for accessing that Something, but it has not the type you would expect. It's called (>>=) and has the following type signature: (>>=) :: Monad m => m a -> (a -> m b) -> m b In this case: (>>=) :: IO a -> (a -> IO b) -> IO b Just look at the type and think about how you can use this function to do what you want. It converts your IO Something to the Something, which you want, but only for a certain function, which is its second argument. Why do people want to get out of the IO monad? Because they interpret the arrow as "going to", and there is a general 'a -> IO a' function (called 'return'), but not an 'IO a -> a' function. A function of this type cannot exist (or it can, but it cannot do anything useful, particularly not what you want). But it's also not needed, because you have (>>=), which is consistent with Haskell's type system and the semantics of IO. Less relevantly, let me also support what Felipe said. Aditya Siram's statement is very misleading, because it suggests that using unsafePerformIO is fine, if you don't overuse it. Wrong! Using it to cast between types is *wrong* and *will* get you into trouble (in this case you are casting from IO Something to Something). Do not use any of the "unsafe" functions, until you understand why you do *not* need them. At that point you may start using them. I'm programming in Haskell for a few years now, and I have used unsafePerformIO exactly once. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/