我正在尝试在Scala中实现BST。我想通过'+'运算符将节点添加到二叉树。但是我在编译期间遇到两个错误
Error:(39, 46) diverging implicit expansion for type Ordering[Any]
starting with method orderingToOrdered in object Ordered
def +[A: Ordering](v: A) : Tree[Any] = add(this, v)
Error:(39, 46) not enough arguments for method add: (implicit evidence$1: Ordering[Any])A$A47.this.Tree[Any].
Unspecified value parameter evidence$1.
def +[A: Ordering](v: A) : Tree[Any] = add(this, v)
这是代码。
sealed trait Tree[+A]{
def add[A: Ordering](tree: Tree[A], v: A) : Tree[A] = tree match {
case EmptyTree => Node(EmptyTree, v, EmptyTree)
case Node(l, x, r) => {
if(x.compare(v) == 1)
Node(add(l, v), x, r)
else
Node(l, x, add (r, v))
}
}
def +[A: Ordering](v: A) : Tree[Any] = add(this, v)
}
有人可以帮助我并说出错误吗?
答案 0 :(得分:1)
我认为问题是运营商+
的界面。
def add[A: Ordering](tree: Tree[A], v: A) : Tree[A]
add
函数接受Tree[A]
并返回Tree[A]
,其中A
受类型类Ordering
约束。这里没有错(但最好在Tree
)的伴随对象中定义它。
def +[A: Ordering](v: A) : Tree[Any] = add(this, v)
+
函数接受tree
类型的值(您假设此add
的{{1}}参数为this
)由类型类A
约束。
这里的第一个问题是,您返回Ordering
。我假设你的意思是Tree[Any]
。
第二个问题是,函数Tree[A]
中的A
不 +
所指的类型参数A
。所以你可能意味着:
this
如果这不是您想要的,则必须通过类型类sealed abstract class Tree[+A: Ordering] {
...
def +(v: A) : Tree[A] = add(this, v)
}
约束A
函数中的+
:
Ordering
在这种情况下,sealed trait Tree[A] {
...
def +(v: A)(implicit ev: Ordering[A]): Tree[A] = add(this, v)
}
可能不再是协变,因为它发生在一个不变的位置。
修改:如下所述,还有机会在函数A
中引入新类型B
。整体代码可能如下所示:
+
第二次编辑:在上面的示例中,有必要引入超类型而不是子类型object Tree {
def add[A](tree: Tree[A], v: A)(implicit ev: Ordering[A]): Tree[A] = ...
}
sealed trait Tree[+A] {
def +[B >: A](v: B)(implicit ev: Ordering[B]): Tree[B] = Tree.add(this, v)
}
... implementation of trait Tree
,因为函数B
需要类型类Tree.add
1}} - 我们无法提供。
以下内容毫无意义,因为它只能证明Ordering[A]
类型的值可以被排序。
B
这甚至都没有编译,因为def +[B <: A](v: B)(implicit ev: Ordering[B]): Tree[B] = ???
发生在一个不变的位置。
A
为了实现def +[B <: A](v: B)(implicit ev: Ordering[A]): Tree[B] = ???
不会出现在不变位置并且为了证明类型A
的值以及类型B
的值可以被排序,我们必须介绍A
作为超级类型。