[Haskell-cafe] so how does one convert an IO a into an a ?

Stefan Holdermans sholderm at students.cs.uu.nl
Thu Jul 8 15:22:20 EDT 2004


Crypt Master,

  CM> Thanks for your help so far, but I am still not
  CM> getting this IO stuff. After reading your
  CM> previous help and reading several articles on
  CM> it I still cant phathom how you convert the IO
  CM> Int into an Int.

Welcome to pure functional programming! :)

Well, since you qualify as a beginner to Haskell, the only good answer one
can give you is "you *cannot* convert from IO Int to Int. Until you're
familiar enough with functional programming in general and Haskell, I'd
recommend not to go with any suggestions people will give you on how to
achieve this. Trust me.

So, first try to ask yourself if it is really needed to get from IO Int to
Int. If you're really convinced that it is and that is for nothing but good
reasons, then ask again and we might carefully point you to a function that
is called unsafePerformIO. (Note: it is called unsafe for a reason.)

Now, think about this for a minute. Consider this a function foo :: Int ->
Int. In Haskell, I can be sure that whenever I call this function with the
same Int argument, I get the same Int result. This observation makes it
quite easy for me to reason about this function, e.g. derive some theorems
for it. So, I know foo 5 == foo 5 will *always* be True as will foo 6 == foo
6.

Then, consider a function bar :: Int -> IO Int. That reads a number from
some file, increments the number by argument value, writes the new number
back to the file, and produces the new number as the result of the function.
(The interaction with the file system makes that the result is included in
an IO value.) So, consecutive calls to this function with the same argument
will produce different values, won't they?

But now imagine now you could somehow convert from IO Int to Int. Then you
could use this mechanism to derive a function bar' :: String -> Int that
does the same as bar but unwraps the IO Int value to produce an Int. Since
consecutive calls to bar' with the same argument are not guaranteed to
produce the same values, we cannot rely on bar' 5 == bar' 5 and bar' 6 ==
bar' 6. Can you see that this troubles reasoning about functions and
programs?

So, to keep the language 'pure' all stuff inside the IO monad should stay
within the IO monad. At first, you might think of this as a limitation, but
if you open yourself for it and think about it for a while, and---even
better---work with it for a while, I'm sure you will start to appreciate it
and start consider it a feature.

Well, I might have simplified things here, and perhaps haven't explained in
a very clear way: I'm sorry for that. However, I think this is more or less
the main reason why the answer to your question should be 'you can't'.

HTH,

Stefan




More information about the Haskell-Cafe mailing list