
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