Python-“is”-like equality operator for Haskell/GHC

旧巷老猫 提交于 2019-12-01 15:17:42

GHC's System.Mem.StableName solves exactly this problem.

There's a pitfall to be aware of:

Pointer equality can change strictness. I.e., you might get pointer equality saying True when in fact the real equality test would have looped because of, e.g., a circular structure. So pointer equality ruins the semantics (but you knew that).

I think StablePointers might be of help here http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Foreign-StablePtr.html Perhaps this is the kind of solution you are looking for:

import Foreign.StablePtr (newStablePtr, freeStablePtr)
import System.IO.Unsafe (unsafePerformIO)

unsafeSameRef :: a -> a -> Bool
unsafeSameRef x y = unsafePerformIO $ do
    a <- newStablePtr x
    b <- newStablePtr y
    let z = a == b
    freeStablePtr a
    freeStablePtr b
    return z;

There's unpackClosure# in GHC.Prim, with the following type:

unpackClosure# :: a -> (# Addr#,Array# b,ByteArray# #)

Using that you could whip up something like:

{-# LANGUAGE MagicHash, UnboxedTuples #-} 
import GHC.Prim

eq a b = case unpackClosure# a of 
    (# a1,a2,a3 #) -> case unpackClosure# b of 
        (# b1,b2,b3 #) -> eqAddr# a1 b1

And in the same package, there's the interestingly named reallyUnsafePtrEquality# of type

reallyUnsafePtrEquality#  :: a -> a -> Int#

But I'm not sure what the return value of that one is - going by the name it will lead to much gnashing of teeth.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!