Scala 带递归的类型排序[Any]的发散隐式展开
我正在尝试在Scala中实现BST。我想通过“+”操作符向二叉树添加一个节点。但是,在编译期间,我遇到了两个错误Scala 带递归的类型排序[Any]的发散隐式展开,scala,Scala,我正在尝试在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:(3
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)
}
有人能帮我看看出了什么问题吗?我想问题出在操作员的界面上
def add[A: Ordering](tree: Tree[A], v: A) : Tree[A]
add
函数接受一个Tree[a]
并返回一个Tree[a]
,其中a
受类型类排序的约束。这里没有错(但最好在树的伴生对象中定义它)
+
函数接受类型为a
的值(您假设add
的树
参数是this
),该值也受类型类排序的约束
这里的第一个问题是,返回一个树[Any]
。我想你指的是树[A]
第二个问题是,函数+
中的A
不是此
所指的类型参数A
。你可能是说:
sealed abstract class Tree[+A: Ordering] {
...
def +(v: A) : Tree[A] = add(this, v)
}
如果这不是您想要的,您必须通过typeclass排序来约束函数+
中的A
:
sealed trait Tree[A] {
...
def +(v: A)(implicit ev: Ordering[A]): Tree[A] = add(this, v)
}
在这种情况下,A
可能不再是协变的,因为它发生在不变的位置
def +[B <: A](v: B)(implicit ev: Ordering[A]): Tree[B] = ???
编辑:如下所述,还有机会在功能+
中引入新类型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
2nd Edit:在上面的示例中,有必要引入超级类型而不是子类型B
,因为函数树.add
需要类型类排序[a]
——我们无法提供
以下内容毫无意义,因为它只证明了B
类型的值可以排序
def +[B <: A](v: B)(implicit ev: Ordering[B]): Tree[B] = ???
因此,为了实现A
不会出现在不变位置,并证明B
类型的值以及A
类型的值可以排序,我们必须将B
作为超级类型引入。感谢您的回答。问题在于,将密封特征树[+A]转换为树[A]会破坏案例类的任何用途,即案例类节点[A](左:树[A],值:A,右:树[A])扩展树[A]或案例对象EmptyTree扩展树[Nothing]另一种可能是引入一种新类型B
,它是a
或a
本身的超级类型:def+[B>:a](v:B)(隐式ev:Ordering[B]):Tree[B]=add(this,v)
。。。但我不确定这是否是你想要的。这是一个很好的解决方案。你能告诉我为什么我们要引入超级类型而不是子类型吗?或者提供一些关于协方差/不变性/逆变换的资料?我已经更新了我的答案,希望这能有所帮助。您可以阅读语言规范中的差异
def +[B <: A](v: B)(implicit ev: Ordering[A]): Tree[B] = ???