【问题标题】:Is it ever possible to detect sharing in Haskell?是否有可能检测到 Haskell 中的共享?
【发布时间】:2013-10-21 18:07:25
【问题描述】:

在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 treeright tree 是否相等,我必须天真地遍历十亿个节点才能发现它们是同一棵树,这应该是显而易见的,因为数据分享。

我不希望有一种简单的方法来发现 Haskell 中的数据共享,但我想知道处理此类问题的典型方法是什么,何时检测共享以提高效率(或例如检测循环数据结构)。

是否有可以检测共享的unsafe 原语?有没有一种众所周知的方法来构建具有显式指针的数据结构,以便您可以比较指针是否相等?

【问题讨论】:

标签: haskell functional-programming


【解决方案1】:

【讨论】:

    【解决方案2】:

    在纯语言 Haskell 中是不可能的。

    但是它在GHC中的实现存在漏洞,比如

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

    【讨论】:

      【解决方案3】:

      有很多方法。

      1. 生成唯一 ID 并将所有内容粘贴到有限映射中(例如 IntMap)。
      2. 最后一个选择的精化版本是制作一个显式图,例如使用fgl
      3. 使用stable names
      4. 使用IORefs (see also),无论包含的类型如何,它们都有EqOrd 实例。
      5. observable sharing 的库。
      6. 如上所述,有reallyUnsafePtrEquality#,但在使用之前你应该了解它的真正不安全之处!

      另见this answer about avoiding equality checks altogether

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-07
        • 1970-01-01
        • 2022-09-23
        • 1970-01-01
        • 2016-05-10
        • 2012-02-14
        • 2010-09-21
        • 2021-11-19
        相关资源
        最近更新 更多