[Haskell] Re: Global Variables and IO initializers

Benjamin Franksen benjamin.franksen at bessy.de
Fri Nov 5 17:14:31 EST 2004

On Friday 05 November 2004 22:07, Keean Schupke wrote:
> So what
> we need is a way in the type system to tell the compiler the function
> must have
> a single unique definition... Something like:
> myRef :: Unique (IORef Int)
> myRef = uniquePerformIO $ newIORef 0
> and then have:
> runUnique :: Unique x -> x

In Eiffel it is called 'once' istead of 'Unique', e.g. (excuse my rusty 
Eiffel, the syntax may be wrong)

class XYZ
	once ref : Int
		...routine body here...
		Result := ...

The semantics is that the routine body is executed at most once, namely when 
the feature is used for the first time.

Note that Eiffel allows arbitrary IO actions to be performed in the body of 
once routines, just like in your Haskell example above. It is interesting to 
note that the Eiffel community is quite aware of the problems this solution 
has, i.e. that the procedure may have side-effects that happen at some 
unpredictable moment in time -- especially when concurrent execution comes 
into play. It is regarded as a matter of programmer discipline to ensure that 
once routines do not have effects visible outside the class in which they are 

Such an appeal to programmer discipline clearly fits not well with the spirit 
of Haskell. I would argue that the actions to be performed inside such a 
'once' or 'unique' initialization must be strictly limited to harmless ones 
like allocation of reference cells. As i pointed out earlier, elements of a 
commutative sub-monad of IO are not automatically harmless. How else can we 
define "harmless" IO actions?

Maybe Ben Rudiak-Gould's idea to use (forall s . ST s) is teh right idea but I 
still don't understand it...


More information about the Haskell mailing list