是否存在GHC特定的“不安全”扩展,询问两个Haskell引用是否指向同一位置?
我知道如果使用不当,这可能会破坏引用透明度。但是,如果使用得非常小心,那么应该没有什么害处(除非我遗漏了一些东西),作为通过短切递归(或昂贵)数据遍历进行优化的手段,例如:用于实现优化的Eq
实例,例如:
instance Eq ComplexTree where
a == b = (a `unsafeSameRef` b) || (a `deepCompare` b)
如果deepCompare
判定为真(但不一定相反),则保证提供unsafeSameRef
。
编辑/ PS :由于答案指向System.Mem.StableName
,我还能够找到正好已经解决了这个问题的论文Stretching the storage manager: weak pointers and stable names in Haskell已超过10几年前......
答案 0 :(得分:12)
GHC的System.Mem.StableName解决了这个问题。
答案 1 :(得分:8)
需要注意的一个陷阱:
指针平等可以改变严格性。也就是说,你可能会得到指向等式的True,而实际上真正的相等性测试会因为例如循环结构而循环。所以指针等式破坏了语义(但你知道)。
答案 2 :(得分:2)
我认为StablePointers可能会有所帮助 http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Foreign-StablePtr.html 也许这就是您正在寻找的解决方案:
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;
答案 3 :(得分:2)
有unpackClosure#
in GHC.Prim,具有以下类型:
unpackClosure# :: a -> (# Addr#,Array# b,ByteArray# #)
使用它可以掀起类似的东西:
{-# 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
在同一个包中,有一个名为reallyUnsafePtrEquality#
的有趣名称
reallyUnsafePtrEquality# :: a -> a -> Int#
但我不确定那个人的回报价值是什么 - 这个名字会导致咬牙切齿。