I just learned about GHC's StablePointer
feature, which is really cool, but I can't figure out why it has won't show things as equal. 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 result of false. 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 still get a result of False. The only way I can get eqStableName
to return True
is when I call makeStableName
on 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 helpful. I already know that every expression is equal to itself, so this doesn't give me any new information. My question is twofold:
- What use cases is
StablePointer
intended to satisfy? - How can we reason about the equality of
StablePointer
. I know that it gives false negatives, but under what circumstances can I expect these to always occur?
Thanks for any insights. They are much appreciated.
-- EDIT --
I discovered that if I build it with ghc
instead of runhaskell
, then Example 2 actually does show that they are equal. Example 1 still fails. The question still stands.
==
instead ofeqStableName
? - BakuriuStablePointer a
had anEq
instance, but now that you've pointed that out, I see that using==
does seem more appropriate for my case, since I am doing equality checks on things of the same type. - Andrew Thaddeus Martin