[Haskell] Real life examples

Ben Rudiak-Gould Benjamin.Rudiak-Gould at cl.cam.ac.uk
Wed Nov 24 17:40:41 EST 2004


John Meacham wrote:

 >On Wed, Nov 24, 2004 at 02:40:52PM +0000, Ben Rudiak-Gould wrote:
 >
 >>But they can all be implemented with George Russell's library plus safe
 >>(pure) uses of unsafePerformIO.
 >
 >George Russell's library is precicly an invalid use of unsafePerformIO.
 >[...] hiding it in a module doesn't make it go away.

Yes it does. :-) If each Haskell environment ships with a correct 
implementation of the library, then its interface is the only part that 
matters. If the unsafePerformIO hack doesn't work in your new Haskell 
compiler, you can replace it with some other magic that does work. It's 
fine for the Haskell environment to hide impure magic behind a pure 
interface -- that's what the language is all about.

 >I am not positive, but it also would also add the overhead of a
 >finitemap lookup across all global variables for every look up.

I'm not positive either, but I don't think it does:

    class InitialValue a where initialValue :: a

    uniqueRef :: (Typeable a, InitialValue a) => IORef a
    uniqueRef = unsafePerformIO (lookupWithRegister (newIORef initialValue))

    ----

    data MyType = ...  deriving Typeable

    instance InitialValue MyType where initialValue = ...

    myEvilTopLevelTWI = (uniqueRef :: IORef MyType)

No, I'm wrong. This can't possibly work, because the dictionaries are 
thread-local and can be rebound. The library should include another 
function with the same type as lookupWithRegister, but which uses a 
per-process dictionary which can't be rebound. Let's call it 
"oncePerType" since I think it's exactly the same as my oncePerType. 
Then replace lookupWithRegister by oncePerType in the definition of 
uniqueRef and it should work. But I've been wrong before. In fact I'm 
usually wrong in this thread.

-- Ben



More information about the Haskell mailing list