在Scheme中,原语eq?
测试其参数是否是同一个对象。例如,在以下列表中
(define lst
(let (x (list 'a 'b))
(cons x x)))
的结果
(eq? (car x) (cdr x))
是真的,而且没有必须与(car x)
和(cdr x)
对等。这允许您为具有大量共享的数据结构编写有效的相等性测试。
Haskell是否可以做同样的事情?例如,请考虑以下二叉树实现
data Tree a = Tip | Bin a (Tree a) (Tree a)
left (Bin _ l _) = l
right (Bin _ _ r) = r
mkTree n :: Int -> Tree Int
mkTree 0 = Tip
mkTree n = let t = mkTree (n-1) in Bin n t t
在每个级别都有共享。如果我创建一个let tree = mkTree 30
的树,我想看看left tree
和right tree
是否相等,天真地我必须遍历十亿个节点才能发现它们是同一棵树,因数据共享而应该是显而易见的。
我不认为有一种简单的方法可以在Haskell中发现数据共享,但我想知道处理这类问题的典型方法是什么,何时为了效率目的检测共享会很好(或者例如检测循环数据结构)。
是否有可以检测共享的unsafe
原语?是否有一种众所周知的方法来构建具有显式指针的数据结构,以便您可以比较指针相等性?
答案 0 :(得分:16)
有很多方法。
IntMap
)。IORef
s(see also),其中包含Eq
和Ord
个实例,无论包含的类型如何。reallyUnsafePtrEquality#
但你应该在使用之前了解它真正不安全的地方!答案 1 :(得分:4)
在Haskell中,纯语言是不可能的。
但是在GHC的实施中,存在漏洞,例如
无论如何,在常规代码中使用它将是非常单一的;至多我可以想象,构建一个高度专业化的库(memoizatoin,哈希表,无论如何),然后提供一个理智的纯API,可能是可以接受的。
答案 2 :(得分:1)