Python-对于Haskell / GHC来说是“类似”的等式运算符

时间:2011-04-18 11:01:22

标签: haskell reference ghc

是否存在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几年前......

4 个答案:

答案 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#

但我不确定那个人的回报价值是什么 - 这个名字会导致咬牙切齿。