有可能在Haskell中检测到共享吗?

有可能在Haskell中检测到共享吗?,haskell,functional-programming,Haskell,Functional Programming,在Scheme中,原语eq?测试其参数是否为同一对象。例如,在下面的列表中 (define lst (let (x (list 'a 'b)) (cons x x))) 结果 (eq? (car x) (cdr x)) 是真的,而且它是真的,无需查看(car x)和(cdr x)。这允许您为具有大量共享的数据结构编写有效的平等性测试 在哈斯克尔,同样的事情可能发生吗?例如,考虑以下二叉树实现< /P> data Tree a = Tip | Bin a (Tree a) (Tre

在Scheme中,原语
eq?
测试其参数是否为同一对象。例如,在下面的列表中

(define lst
  (let (x (list 'a 'b))
    (cons x x)))
结果

(eq? (car x) (cdr x))
是真的,而且它是真的,无需查看
(car x)
(cdr x)
。这允许您为具有大量共享的数据结构编写有效的平等性测试

在哈斯克尔,同样的事情可能发生吗?例如,考虑以下二叉树实现< /P>
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
创建一棵树,并且我想看看
左树
右树
是否相等,那么很天真地,我必须遍历十亿个节点才能发现它们是同一棵树,这应该是显而易见的,因为数据共享

我不希望在Haskell中有一种简单的方法来发现数据共享,但我想知道处理这类问题的典型方法是什么,什么时候为了提高效率而检测共享比较好(或者检测循环数据结构)


是否存在可以检测共享的
不安全的
原语?有没有一种众所周知的方法可以使用显式指针构建数据结构,以便比较指针相等性?

有。另请参见

这在纯语言哈斯克尔中是不可能的

但在GHC中的实施过程中存在漏洞,例如

  • 使用或
  • 自省库如

在任何情况下,在常规代码中使用它都是非常不划算的;至多我可以想象,为某种东西(备忘录、哈希表等)构建一个高度专业化的库,然后提供一个健全、纯粹的API,这可能是可以接受的

  • 生成唯一的ID并将所有内容粘贴在有限的映射中(例如)
  • 最后一个选择的改进版本是制作一个显式图形,例如使用
  • 使用
  • Use(),它既有
    Eq
    又有
    Ord
    实例,而不管包含的类型如何
  • 这里有图书馆供学生使用
  • 如上所述,确实存在
    不安全性#
    ,但在使用它之前,您应该了解它的真正不安全之处

    也见。

    参见当你这样做时,总是考虑你的数据结构包含Na或其他不等于自身的值的可能性。您的优化可能是一个突破性的优化。