
Hey everyone! This is probably a stupid question, but is there a way to get stuff out of a IO handle? If I do something with an IO handle, reading in data from a file for example and then do something with the data, is there a way to get the results out of the handle, comparable to the return in a do block? Or do all operations on the data have to happen inside the handle? Thanks Raf

On 24/06/2011 1:23 AM, Raphael Päbst wrote:
Hey everyone! This is probably a stupid question,
No such thing. :)
but is there a way to get stuff out of a IO handle?
You have to bind it in the IO monad. This means, for example, if you have a handle called `h', in a do block: line <- hGetLine h This is syntactic sugar for hGetLine h >>= (\line -> ...), where the `...' is whatever follows in the do block.
If I do something with an IO handle, reading in data from a file for example and then do something with the data, is there a way to get the results out of the handle, comparable to the return in a do block?
return is actually the opposite(!) -- it puts something *in* the monad. I think you may have handles and the IO monad itself confused, but if you'd like to post some sample code, we could show you how to achieve what you want, and explain it more fully. :) Here are some small examples of using handles and IO: -- these are provided by System.IO: stdin :: Handle stdout :: Handle hGetLine :: Handle -> IO String hPutStrLn :: Handle -> String -> IO () -- from Control.Monad: forever :: Monad m => m a -> m b -- an example of using a handle: copyLine :: Handle -> Handle -> IO () copyLine inh outh = do line <- hGetLine inh hPutStrLn outh line -- The above 'do' block can be simplified to: -- hGetLine inh >>= (\line -> hPutStrLn outh line) -- and then to: -- hGetLine inh >>= hPutStrLn outh main :: IO () main = forever $ copyLine stdin stdout .. it's a bit verbose, but perhaps helpful. If it's returning the result of an op on a handle, it's much the same: copyLineAndReturn :: Handle -> Handle -> IO String copyLineAndReturn inh outh = do line <- hGetLine inh hPutStrLn outh line return line -- hGetLine inh >>= (\line -> hPutStrLn outh line >> return line)
Thanks
Raf
Cheers, Arlen

The short answer is no. The longer answer depends on what you mean by "get
out". You can take the result of an IO action and pass it to a pure function
like so:
do
result <- someIOAction
return $ somePureFunction result
or alternately:
someIOAction >>= return . somePureFunction
If you want to know if you can do something like:
someFunction :: Int -> Int
someFunction n = escapeIO $ someIOAction n
then the answer is you shouldn't. It is technically possible, by using a
function that every experienced haskell developer will tell you to never
ever ever ever ever ever ever ever (get the picture) use, which is
unsafePerformIO, but if you use unsafePerformIO it's likely that your code
won't do what you actually expect it to do, even if the type signatures all
check correctly. The IO Monad serves a very important purpose and implies
certain things about a computation, likewise the absence of the IO Monad
implies certain guarantees, and when you break those guarantees bad things
happen.
-R. Kyle Murphy
--
Curiosity was framed, Ignorance killed the cat.
On Thu, Jun 23, 2011 at 11:23, Raphael Päbst
Hey everyone! This is probably a stupid question, but is there a way to get stuff out of a IO handle? If I do something with an IO handle, reading in data from a file for example and then do something with the data, is there a way to get the results out of the handle, comparable to the return in a do block? Or do all operations on the data have to happen inside the handle? Thanks
Raf
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

If you want to know if you can do something like:
someFunction :: Int -> Int someFunction n = escapeIO $ someIOAction n
then the answer is you shouldn't. It is technically possible, by using a function that every experienced haskell developer will tell you to never ever ever ever ever ever ever ever (get the picture) use, which is unsafePerformIO, but if you use unsafePerformIO it's likely that your code won't do what you actually expect it to do, even if the type signatures all check correctly. The IO Monad serves a very important purpose and implies certain things about a computation, likewise the absence of the IO Monad implies certain guarantees, and when you break those guarantees bad things happen.
I'd like to clarify a bit here. The unsafePerformIO function has a use, and should be used, but only in the right circumstances. The problem is that often a function is referentially transparent, but haskell cannot prove that it is because it uses the IO Monad. The circumstance in which this crops up is usually when you use the FFI. The function you call in C might return a pointer to something, rather than the data itself. The pointer will usually be different every time, so the result isn't referentially transparent. However, if you extract the data from the pointer, that data _is_ referentially transparent and is, as such, a good use case for unsafePerformIO. So I would say an experienced programmer would say to never use it if you don't know what you are doing, but if you do, use it when you need it.

I had started to say something about the circumstances under which you
actually can use unsafePerformIO, but it sort of bogged down the reply and
muddled the point I was trying to make. You seem to have done a better job
explaining the circumstances under which you can actually use unsafePerfomIO
safely than I was able to at the time.
-R. Kyle Murphy
--
Curiosity was framed, Ignorance killed the cat.
On Thu, Jun 23, 2011 at 19:46, Jared Hance
If you want to know if you can do something like:
someFunction :: Int -> Int someFunction n = escapeIO $ someIOAction n
then the answer is you shouldn't. It is technically possible, by using a function that every experienced haskell developer will tell you to never ever ever ever ever ever ever ever (get the picture) use, which is unsafePerformIO, but if you use unsafePerformIO it's likely that your code won't do what you actually expect it to do, even if the type signatures all check correctly. The IO Monad serves a very important purpose and implies certain things about a computation, likewise the absence of the IO Monad implies certain guarantees, and when you break those guarantees bad things happen.
I'd like to clarify a bit here. The unsafePerformIO function has a use, and should be used, but only in the right circumstances. The problem is that often a function is referentially transparent, but haskell cannot prove that it is because it uses the IO Monad.
The circumstance in which this crops up is usually when you use the FFI. The function you call in C might return a pointer to something, rather than the data itself. The pointer will usually be different every time, so the result isn't referentially transparent. However, if you extract the data from the pointer, that data _is_ referentially transparent and is, as such, a good use case for unsafePerformIO.
So I would say an experienced programmer would say to never use it if you don't know what you are doing, but if you do, use it when you need it.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Thanks for your replies!
A short example of what I'm doing:
handle <- connectTo ... --opening the handle on a tcp connection
hPut handle message -- sending a ByteString
answer <- hGet handle n -- getting the answer back from the server
hClose handle
I have now several things I would like to do with the answer and my
question is, if I should put the functions into the handle or if I can
make the function with the handle of a type that returns answer, not
of IO () as it is currently.
Does this make sense? I hope so.
Raf
On 6/24/11, Kyle Murphy
I had started to say something about the circumstances under which you actually can use unsafePerformIO, but it sort of bogged down the reply and muddled the point I was trying to make. You seem to have done a better job explaining the circumstances under which you can actually use unsafePerfomIO safely than I was able to at the time.
-R. Kyle Murphy -- Curiosity was framed, Ignorance killed the cat.
On Thu, Jun 23, 2011 at 19:46, Jared Hance
wrote: If you want to know if you can do something like:
someFunction :: Int -> Int someFunction n = escapeIO $ someIOAction n
then the answer is you shouldn't. It is technically possible, by using a function that every experienced haskell developer will tell you to never ever ever ever ever ever ever ever (get the picture) use, which is unsafePerformIO, but if you use unsafePerformIO it's likely that your code won't do what you actually expect it to do, even if the type signatures all check correctly. The IO Monad serves a very important purpose and implies certain things about a computation, likewise the absence of the IO Monad implies certain guarantees, and when you break those guarantees bad things happen.
I'd like to clarify a bit here. The unsafePerformIO function has a use, and should be used, but only in the right circumstances. The problem is that often a function is referentially transparent, but haskell cannot prove that it is because it uses the IO Monad.
The circumstance in which this crops up is usually when you use the FFI. The function you call in C might return a pointer to something, rather than the data itself. The pointer will usually be different every time, so the result isn't referentially transparent. However, if you extract the data from the pointer, that data _is_ referentially transparent and is, as such, a good use case for unsafePerformIO.
So I would say an experienced programmer would say to never use it if you don't know what you are doing, but if you do, use it when you need it.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (4)
-
Arlen Cuss
-
Jared Hance
-
Kyle Murphy
-
Raphael Päbst