GHC StablePointer Equality Concept

I just found out about the GHC StablePointer function, which is really cool, but I cannot understand why it will not show things as equals. Here is my test case:

 -- Example 1 import System.Mem.StableName data Wrapper = Wrapper { getWrapper :: Int -> Bool } myFunc :: Int -> Bool myFunc = (> 4) main :: IO () main = do let m = Wrapper myFunc a <- makeStableName $ getWrapper m b <- makeStableName $ getWrapper m print (a `eqStableName` b) putStrLn "Done" 

Pretty simple, but when I do runhaskell with GHC 7.8.4, I get a false result. What about a simpler case? Let's try this:

 -- Example 2 import System.Mem.StableName main :: IO () main = do let m = (+2) :: Int -> Int n = m a <- makeStableName m b <- makeStableName n print (a `eqStableName` b) putStrLn "Done" 

I am still getting the result False. The only way to get eqStableName to return True is when I call makeStableName in the same exact bound variable. Like this:

  -- in this example, r can be anything a <- makeStableName r b <- makeStableName r print (a `eqStableName` b) 

But this is no longer useful. I already know that each expression is equal to itself, so this does not give me any new information. My question is twofold:

  • What use StablePointer are StablePointer designed to satisfy?
  • How can we talk about StablePointer equality. I know that he gives false negatives, but under what circumstances can I expect that they will always take place?

Thanks for any ideas. They are very much appreciated.

- EDIT -

I found that if I build it using ghc instead of runhaskell , then example 2 really shows that they are equal. Example 1 is still not running. The question is still standing.

+7
haskell ghc
source share
1 answer

The reason that they return False is probably laziness. In the GHC, m and n will refer to different thunks, since they are not yet rated. makeStableName does not force the value. If you manually run thunk, they will be the same:

  let m = Wrapper myFunc a <- makeStableName $! getWrapper m b <- makeStableName $! getWrapper m print (a `eqStableName` b) 

Fingerprints True ( $! getWrapper force the value returned by getWrapper in WHNF).

Note that if you do not use runhaskell , but instead compile with -O1 , the GHC will actually compile this code so that it prints True . From a look at Core, it seems that the GHC has made an embedding of m and getWrapper to effectively execute the code:

 a <- makeStableName myFunc b <- makeStableName myFunc 

Which, of course, generates the same stable pointer.

So, if you want maximum equality, always force your values ​​before creating stable pointers for them. There is no guarantee, although if the two values ​​are equal, they are assigned the same stable pointers.

If you haven't read it yet, I also recommend reading the Warehouse Manager Stretch , which explains the implementation of stable pointers.

+8
source share

All Articles