[Haskell] Re: Global Variables and IO initializers
jules at jellybean.co.uk
Fri Nov 5 15:12:49 EST 2004
On 5 Nov 2004, at 19:03, MR K P SCHUPKE wrote:
>> You don't want stdin/stdout/stderr?
> Also these are only available in the IO monad...
>> without breaking referential transparency
>> by use of unsafePerformIO hack.
> I don't understand this still... how can it not break referntial
> For example consider if stdin were available outside the IO monad.
> Could someone give an example of what these things are that need to be
> and that are safe.
The typical example is an IORef.
myRef :: IORef Int
myRef = unsafePerformIO $ newIORef 0
Now it's perfectly safe for myRef to exist outside the IO monad: all it
is, is some kind of pointer to the actual value. Of course, we can't do
anything to it outside the IO monad, but it can exist.
Therefore, if it is at the toplevel, it can be referenced by all the
other functions in the same module. The functions therefore share a
common 'pointer' to a value: however none of them can actually access
the value or change it without using the IO monad, as is right and
This is typical of the kind of commutative operations that Koen
proposes: what it is really about is 'fresh names'. newIORef returns a
'fresh name' for a 'box' which stores things. (I notice that name
supply is one of the key issues for John Petersen too).
There appears to be no problem in principle with having such objects
around at the top level, but haskell provides no syntax to create them
(safely). The syntax above is obviously 'wrong' in that it is rather
assuming that two different calls to unsafePerformIO $ newIORef 0 will
return different values, which violates ref. integrity.
The compiler has something like an internal fresh name monad: every
time you define a new top-level value, it is given some fresh
(internal) name. Most language compilers can be thought of as operating
like this, but haskell makes it hard to get at the bit of this monad we
More information about the Haskell