【问题标题】:Structurally Enforcing No Red Children Of Red Node在结构上强制没有红色节点的红色子节点
【发布时间】:2016-07-24 10:42:38
【问题描述】:

在研究Learn You A Haskell For Great GoodPurely Functional Data Structures 时,我想尝试重新实现Red Black tree,同时尝试在结构上强制执行另一个树不变量。

解释冈崎的代码,他的节点看起来像这样:

import Data.Maybe

data Color = Red | Black

data Node a = Node {
    value :: a,
    color :: Color,
    leftChild :: Maybe (Node a),
    rightChild :: Maybe (Node a)}

红黑树的一个属性是a red node cannot have a direct-child red node,所以我尝试将其编码如下:

import Data.Either

data BlackNode a = BlackNode {
    value :: a,
    leftChild :: Maybe (Either (BlackNode a) (RedNode a)),
    rightChild :: Maybe (Either (BlackNode a) (RedNode a))}
data RedNode a = RedNode {
    value :: a,
    leftChild :: Maybe (BlackNode a),
    rightChild :: Maybe (BlackNode a)}

这会输出错误:

Multiple declarations of `rightChild'
Declared at: :4:5
             :8:5


Multiple declarations of `leftChild'
Declared at: :3:5
             :7:5


Multiple declarations of `value'
Declared at: :2:5
             :6:5

我已尝试对之前的代码进行多次修改,但都无法编译。这样做的正确方法是什么?

【问题讨论】:

  • 遗憾的是,您不能以相同的方式命名两个不同类型的两个字段。尝试将它们命名为blackValue,..,blackRightChild,红色对应物也类似。
  • @chi 愿你与你同在!那行得通!我很惊讶 Haskell 有这个限制 - 永远不会猜到。你会写这个作为答案吗?我已经花了几个小时来解决这个问题并在整个互联网上进行搜索 - 也许它会对其他人有所帮助。
  • 虽然您当然可以强制执行“没有红色节点和红色子节点”不变量,但事实证明,在不破坏性能的情况下强制执行完整的红黑树不变量是非常困难的。在您浏览过有关它的论文之后,我怀疑您会得出与我相同的结论——通常情况下,您最好还是硬着头皮使用 2-3-4 棵树。
  • 实际上有一个新的 GHC 功能可以在即将发布的 8.0 版本中解除此限制。
  • @dfeuer 感谢您的评论。如果您愿意分享链接,我将不胜感激。是否有可能强制执行所有内容?我不知道如何强制执行基本的搜索树不变量(即左子树的键是 \leq,而右子树的键是 \geq)。

标签: haskell red-black-tree recursive-datastructures


【解决方案1】:

不同的记录类型必须有不同的字段名称。例如,这是不允许的:

data A = A { field :: Int }
data B = B { field :: Char }

虽然没关系:

data A = A { aField :: Int }
data B = B { bField :: Char }

前者会尝试定义两个投影

field :: A -> Int
field :: B -> Char

但是,唉,我们不能有两种类型的名称。 (至少,没那么容易……) 这个问题在 OOP 语言中不存在,其中字段名称永远不能单独使用,但它们必须立即应用于某些对象,如 object.field - 这是明确的,前提是我们已经知道 @987654325 的类型@。 Haskell 允许独立投影,这让事情变得更加复杂。

后一种方法改为定义

aField :: A -> Int
bField :: B -> Char

并避免该问题。

正如上面的@dfeuer cmets,GHC 8.0 可能会放宽这个限制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-12
    • 1970-01-01
    • 1970-01-01
    • 2014-01-13
    • 2016-01-22
    相关资源
    最近更新 更多