I've used it in a set of bottom-up applicative parser combinators, so that I could make them provide an Applicative interface, but be warned, allocation of a stable name involves a fair bit more than just doing a pointer comparison. IIRC, Andy Gill has a paper on a related approach, which he uses in his version of Lava. Although I haven't benchmarked it, I have a strong suspicion that it is likely cheaper to just unsafePerformIO to allocate a new IORef (), add that as a member, and to check those for equality. Of course you then need to be disciplined about not sharing the refs. This is the approach taken by the mainstream Lava distribution. Also, be warned that common subexpression elimination might yield more positives than you would expect from a naive source reading. -Edward Kmett On Wed, Mar 3, 2010 at 1:59 PM, Milan Straka <fox@ucw.cz> wrote:
Hi,
thanks for enlightening me :) I wished for something like this some time ago...
Milan
You should seq or use a bangpattern on the arguments before taking the stable names to ensure that the result is reproducible if the input thunks may later be forced.
let y = 1 + 1; x = id y in (ptrEqual x y, x `seq` y `seq` ptrEqual x y) (False,True)
a === b = a `seq` b `seq` unsafePerformIO $ (==) <$> makeStableName a <*> makeStableName b
let y = 1 + 1; x = id y in (x === y, x `seq` y `seq` x === y) (True,True)
This may be less of a problem if your tree has bang patterns, but even there it it sometimes easy to trip up and make a mistake with the unforced root of a tree.
-Edward Kmett
On Wed, Mar 3, 2010 at 1:08 PM, Jonathan Cast <jonathanccast@fastmail.fm wrote:
On Wed, 2010-03-03 at 18:58 +0100, Axel Simon wrote:
On 03.03.2010, at 17:30, Milan Straka wrote:
Any easy way of comparing pointers? I mean, if I have something like Tree a = N | B (Tree a) a (Tree a) and have (l::Tree a) and (r::Tree a), can I ask about the "physical equality"?
You can! Despite the names appearing in the following code, the following is safe:
-- | Equality on pointers. ptrEqual :: a -> a -> Bool ptrEqual x y = unsafePerformIO $ do nx <- makeStableName x ny <- makeStableName y return (nx==ny)
Safe but not pure?
jcc
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries