How to get rid of IO
I have something of type
IO a, but I need something of type
a, so how do I get rid of that annoying
...so in other words, you've got e.g.
thatIOThingie :: IO Datum, but
regularThingie :: Datum is what the rest of your code is expecting.
Well, there are a few ways to do this...
Abstracting dependent code as functions
Regarding the code expecting
regularThingie: If you're able to make it into a function e.g:
whateverYouNeedToDoWith :: Datum -> Value
- Using your new function:
fmap whateverYouNeedToDoWith thatIOThingie
- Use lifting combinators
- You can also use:
liftM whateverYouNeedToDoWith thatIOThingie
- ...you've got several
IOthings to deal with? No problem:
liftM3 thePurposeOfUsing thisIOTingie thatIOThingie anotherIOThingie
Using I/O actions more directly
If changing the code expecting
regularThingie is impractical, then:
do regularThingie <- thatIOThingie return (whateverYouNeedToDoWith regularThingie)
- Use the basic bind operations for I/O:
thatIOThingie >>= \ regularThingie -> return (whateverYouNeedToDoWith regularThingie)
Yes, each of those techniques produces more
IO thingies. That's the real beauty of it: if you have a value that is dependent on the environment (i.e. a
thingie value) you can use it as a regular value as shown above, but the result will always be another
IO value (The result will depend on the environment because it uses a value dependent of the environment).
This is no problem, just accept it.
So by using those techniques, you can use I/O while keeping all the safety properties of a pure functional programming language.
You don't understand: I have an
IO String and I just want to remove the
IO bit - how can I do that?
Alright, here's the short answer: You don't.
More information, please
If there was a way to do it e.g.
doItNow :: IO a -> a then everyone else can also use it:
clickHereToWin = doItNow (stealCreditCardDetails >> selectRandomPrize)
Is getting that darn
String really that important - why are you even using Haskell?
That is why you cannot get rid of
IO in Haskell; think of it instead as a special safety-belt which stops your programs falling out of the computer-carnival ride. Albert Lai posted another good explanation on comp.lang.functional:
So the biggest parts of your Haskell programs should be pure, non-I/O functions which crunch all the data, leaving a thin layer of I/O code for retrieving the necessary information (e.g. from a database) and displaying the results (e.g. to a V.R. headset).
Instead of finding a way to get rid of
IO, focus on keeping the I/O layer of your Haskell programs as thin as possible by maximising the code which is pure.
(Alternately, if you could get rid of
IO then so could everyone else...)