On 27-Jul-1999, Frank A. Christoph <[EMAIL PROTECTED]> wrote:
> > I would like to have a comparison instruction that compares the internal
> > reference of two objects.
> > Let's call it "req".
> >
> > req :: a -> a -> Bool
> 
> By coincidence, I was just looking at GHC's documentation on stable names
> and pointers, and it seems relevant here.
> 
> http://research.microsoft.com/users/t-simonm/ghc/Docs/latest/libraries/libs-
> 14.html
> 
> Something like this might do the job for you:
> 
> req a b = unsafePerformIO $ do
>    a' <- makeStableName a
>    b' <- makeStableName b
>    return (a' == b')

This is an unsafe use of unsafePerformIO, because `req' is not
referentially transparent.

Instead, you should use

    ptrEqual :: a -> a -> IO Bool
    ptrEqual a b = do
            a' <- makeStableName a
            b' <- makeStableName b
            return (a' == b')

and the call to unsafePerformIO should be moved outwards, into the caller,
to the point at which referential transparency is preserved, e.g.

        equal x y = unsafePerformIO $ do
                ptrEq <- ptrEqual x y
                return (ptrEq || deep_equals x y)
        
Note that unlike `req', `equal' here _is_ referentially transparent.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger [EMAIL PROTECTED]        |     -- the last words of T. S. Garp.


Reply via email to