Scala 带递归的类型排序[Any]的发散隐式展开

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

我正在尝试在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)
}

有人能帮我看看出了什么问题吗?

我想问题出在操作员的界面上

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] = ???