[Haskell] Re: Global Variables and IO initializers

Adrian Hey ahey at iee.org
Sat Nov 6 01:20:06 EST 2004

On Friday 05 Nov 2004 7:03 pm, MR K P SCHUPKE wrote:
> Could someone give an example of what these things are that need to be
> initialised and that are safe.

Here's a utility I've concocted for dealing with partial ordering
constraints on initialisation of foreign libraries..

 oneShot :: IO a -> IO (IO a)
 oneShot io = mdo mv <- newMVar $ do a <- io
                                     let loop = do putMVar mv loop
                                                   return a
                  return $ do act <- takeMVar mv

The idea being that oneShot takes a real initialising action
as argument and returns a new action which will perform the
real initialisation at most once, no matter how many times it's

Suppose I want to use this to create a userInit (which is exported)
from a realInit (which isn't exported).

Currently I have to write..

 userInit :: IO <whatever>
 userInit = unsafePerformIO $ oneShot realInit

but I think what I would really like is something like
this perhaps..

 -- For use from SafeIO monad
 oneShotSafeIO :: IO a -> SafeIO (IO a)
 <same definition>

 -- For use from IO monad
 oneShotIO :: IO a -> IO (IO a)
 oneShotIO io = liftSafeIO $ oneShotSafeIO io

 userInit :: IO <whatever>
 userInit <- oneShotSafeIO realInit

Though this could be simplified if SafeIO could be made a
sub-type of IO I guess (but I don't know a way to do this).

Adrian Hey

More information about the Haskell mailing list