
Hi, I have a silly question, Can i get things out of IO monad? for example, function 'anotherFun' doesn't work. genFunc :: IO String anotherFunc :: (Monad m) => m String -- m is a complex monad and is not an IO monad -- m is not an instance of MonadIO so liftIO will not work anotherFunc = do genStr <- genFunc return genStr I just want to get something from IO monad and wrap it with some other monad. Is there anyway to do that? Thanks.

On Thu, May 5, 2011 at 5:48 PM,
Hi,
I have a silly question, Can i get things out of IO monad?
for example, function 'anotherFun' doesn't work.
genFunc :: IO String
anotherFunc :: (Monad m) => m String -- m is a complex monad and is not an IO monad -- m is not an instance of MonadIO so liftIO will not work anotherFunc = do genStr <- genFunc return genStr
I just want to get something from IO monad and wrap it with some other monad. Is there anyway to do that? Thanks.
Not being able to do that is the entire point of the IO monad. What are you trying to do? Antoine
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Generally every function that uses something in the IO monad *has* to
return something in the IO monad or a monad transformer that has IO at
its base.
This is so that you can track any function that could potentially have
some side-effect just by looking at the signature.
There is a function called "unsafePerformIO" which subverts this by
turning an 'IO a' into an 'a', but it's not really meant for general
use.
This frustrated me in the beginning too, but I found that if I was
using 'unsafePerformIO' too much the design was probably bad.
-deech
On Thu, May 5, 2011 at 5:48 PM,
Hi,
I have a silly question, Can i get things out of IO monad?
for example, function 'anotherFun' doesn't work.
genFunc :: IO String
anotherFunc :: (Monad m) => m String -- m is a complex monad and is not an IO monad -- m is not an instance of MonadIO so liftIO will not work anotherFunc = do genStr <- genFunc return genStr
I just want to get something from IO monad and wrap it with some other monad. Is there anyway to do that? Thanks. _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Fri, May 6, 2011 at 12:25 AM, aditya siram
There is a function called "unsafePerformIO" which subverts this by turning an 'IO a' into an 'a', but it's not really meant for general use.
This frustrated me in the beginning too, but I found that if I was using 'unsafePerformIO' too much the design was probably bad.
If you are a beginner, you should never use anything that starts with 'unsafe'. And you should *never* use 'unsafePerformIO'. And you should *NEVER* use 'unsafeCoerce'. Cheers, =) -- Felipe.

On Friday 06 May 2011 05:28:35, Felipe Almeida Lessa wrote:
If you are a beginner, you should never use anything that starts with 'unsafe'.
Basically yes, use something beginning with 'unsafe' only when you know why it's not unsafe in your specific case. But of course there are different levels of unsafeness, Data.Array.Base.unsafeAt for example is relatively benign (same as in other languages: if you don't let the compiler check array bounds and screw your check up, you can get nonsense or segfaults, but it's relatively easy to understand and control).
And you should never use 'unsafePerformIO'. And you should NEVER use 'unsafeCoerce'.
Those two indeed have a different calibre, use them only whenYouReallyKnowWhatYouAreDoing. They have their uses and sometimes are the right thing, but like goto, in most cases one is tempted to use them, one shouldn't.
Cheers, =)
-- Felipe.

Thanks guys, I thinks I can stop trying to get things out of IO now.
Instead I should see if I could make my monad as an instance of MonadIO, so
I can use liftIO, which should be safe I believe.
2011-5-6下午3:46,Daniel Fischer
On Friday 06 May 2011 05:28:35, Felipe Almeida Lessa wrote:
If you are a beginner, you should never use anything that starts with
'unsafe'.
Basically yes, use something beginning with 'unsafe' only when you know why
it's not unsafe in your specific case.
But of course there are different levels of unsafeness,
Data.Array.Base.unsafeAt for example is relatively benign (same as in other
languages: if you don't let the compiler check array bounds and screw your
check up, you can get nonsense or segfaults, but it's relatively easy to
understand and control).
And you should never use 'unsafePerformIO'. And you
should NEVER use 'unsafeCoerce'.
Those two indeed have a different calibre, use them only
whenYouReallyKnowWhatYouAreDoing.
They have their uses and sometimes are the right thing, but like goto, in
most cases one is tempted to use them, one shouldn't.
Cheers, =)
--
Felipe.

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/
participants (6)
-
aditya siram
-
Antoine Latter
-
Daniel Fischer
-
Ertugrul Soeylemez
-
Felipe Almeida Lessa
-
jianqiuchi@gmail.com