Stefan Reich wrote: > > DiffArray is an example of a good use for unsafePerformIO: it uses > > imperative operations to implement a pure API. The DiffArray is made of > > mutable objects under the hood, but as far as the programmer is > > concerned it behaves just like a pure Array. > > I'd like to ask a general question about unsafePerformIO: What exactly > does unsafe mean? Just "impure" or rather "may lead to all kinds of > problems, you better don't use this"?
Essentially both. Haskell assumes purity (referential transparency), so impurity is likely to result in "all kinds of problems". If you think of the IO monad as a state transformer, i.e. IO a = World -> (World, a) unsafePerformIO basically applies the transformation to whichever World value happens to be available at the time (i.e. the current system state, where "current" is unspecified), and that depends upon the details of the evaluation mechanism. Using unsafePerformIO is safe if the transformer generates the same result result for all possible World values. If it generates different results for different World values, you risk running into problems. Note: even if you are willing to accept one of many possible "valid" values, you need to allow for the fact that the expression may be evaluated multiple times. E.g. if you have: let x = unsafePerformIO foo where foo may produce different values, you could find that x /= x. The opposite problem is also possible, i.e. that distinct occurrences of the same expression could be merged. A common example is in attempting to create "global variables": x, y :: IORef Int x = unsafePerformIO $ newIORef 0 y = unsafePerformIO $ newIORef 0 Due to optimisation, x any y may end up referring to the same IORef. In short: Haskell assumes referential transparency; if you break it, all bets are off. -- Glynn Clements <[EMAIL PROTECTED]> _______________________________________________ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users