# How to make Claessen's Refs Ord-able?

**Mike Gunter
**
m@ryangunter.com

*Tue, 19 Mar 2002 15:56:57 -0800*

I'd like to extend the Ref type for observable sharing of Koen Claessen's
Ph.D. thesis:
>* import IOExts ( IORef, newIORef, readIORef, writeIORef, unsafePerformIO )
*>*
*>* newtype Ref a = MkRef (IORef a)
*>*
*>* ref :: a -> Ref a
*>* ref x = MkRef (unsafePerformIO (newIORef x))
*>*
*>* deref :: Ref a -> a
*>* deref (MkRef r) = unsafePerformIO (readIORef r)
*>*
*>* (<==>) :: Ref a -> Ref a -> Bool
*>* (MkRef ref1) <==> (MkRef ref2) = ref1 == ref2
*
to make it possible for the Refs to be the keys for efficient finite maps.
I.e. I want something with at least an efficient Ord-like compare and maybe
also a hash function.
The closest I've got is:
>* type UniqTy = Integer
*>* newtype RefWInt a = RefWInt (UniqTy, a) deriving (Show)
*>*
*>* curUniqInt :: IORef UniqTy
*>* curUniqInt = unsafePerformIO (newIORef 0)
*>* newRef a = do
*>* v <- readIORef curUniqInt
*>* writeIORef curUniqInt (v + 1)
*>* return (v, a)
*>*
*>* refWInt x = RefWInt (unsafePerformIO (newRef x))
*
which works properly for this program alone:
>* tri_1 = (a, b, b1)
*>* where a = refWInt "a"
*>* b = refWInt "b"
*>* b1 = refWInt "b"
*
yielding (RefWInt (0,"a"),RefWInt (1,"b"),RefWInt (2,"b")).
But if I add another copy of the same definition:
>* tri_2 = (a, b, b1)
*>* where a = refWInt "a"
*>* b = refWInt "b"
*>* b1 = refWInt "b"
*
and use it by uncommenting the second line here:
>* main = print tri_1
*>* -- >> print tri_2
*
I get:
(RefWInt (0,"a"),RefWInt (1,"b"),RefWInt (1,"b"))
(RefWInt (0,"a"),RefWInt (1,"b"),RefWInt (1,"b"))
with ghc. (I get the desired
(RefWInt (0,"a"),RefWInt (1,"b"),RefWInt (2,"b"))
(RefWInt (3,"a"),RefWInt (4,"b"),RefWInt (5,"b"))
with ghci.)
Can I write code to always get the desired behavior? How?
thanks,
mike