K => Ordered[K] 中没有可用的隐式视图。涉及默认参数的应用程序发生错误

No implicit view available from K => Ordered[K]. Error occurred in an application involving default arguments

我正在尝试在 Scala 中实现一个基于权重树的集合。我有以下 class 层次结构:

case class Node[K, V](key: K, value: Option[V] = None, left: Option[Node[K, V]] = None, right: Option[Node[K, V]] = None, size: Int = 1)(implicit ord: K => Ordered[K])

case class Tree[K, V](root: Option[Node[K, V]] = None, alpha: Double = 0.25)(implicit ord: K => Ordered[K])

case class WBTreeSet[K](tree: Tree[K, Nothing] = Tree[K, Nothing]())(implicit ord: K => Ordered[K])

类 隐式获取 Ordered[K] 以便我可以比较类型 K 的元素并构建树。

当我尝试编译代码时,出现以下错误:

No implicit view available from K => Ordered[K].
Error occurred in an application involving default arguments.
case class WBTreeSet[K](tree: Tree[K, Nothing] = Tree[K, Nothing]())(implicit ord: K => Ordered[K]) {

not enough arguments for method apply: (implicit ord: K => Ordered[K])Tree[K,Nothing] in object Tree.
Unspecified value parameter ord.
Error occurred in an application involving default arguments.
case class WBTreeSet[K](tree: Tree[K, Nothing] = Tree[K, Nothing]())(implicit ord: K => Ordered[K]) {

当我在 WBTreeSet 中删除 tree 的默认值时,代码编译。

我是第一次使用Scala,已经搜索了很多类似的问题,但是还是无法解决这个问题。有没有办法在不改变 classes 结构的情况下解决这个问题,或者我应该用另一种方式来解决这个问题?

尝试重载 apply 方法:

case class Node[K, V](key: K, value: Option[V] = None, left: Option[Node[K, V]] = None, right: Option[Node[K, V]] = None, size: Int = 1)(implicit ord: K => Ordered[K])

case class Tree[K, V](root: Option[Node[K, V]] = None, alpha: Double = 0.25)(implicit ord: K => Ordered[K])

case class WBTreeSet[K](tree: Tree[K, Nothing])(implicit ord: K => Ordered[K])
object WBTreeSet {
  def apply[K](implicit ord: K => Ordered[K]): WBTreeSet[K] = WBTreeSet(Tree[K, Nothing]())
}

我想您希望将 WBTreeSet 的隐式 ord 参数传递给 tree 参数的默认值。不幸的是,这不会起作用,因为在 Scala 中,默认参数值不能引用同一参数列表或后续参数列表中的其他参数值,例如

def thisWillWork(a: Int)(b: Int = a*2) = ???
def thisWillNotWork(a: Int, b: Int = a*2) = ???
def thisWillNotWork(a: Int = b*2)(b: Int) = ???

那,加上隐式参数只能在最后一个参数列表中传递的事实意味着你的 tree 参数默认值无法访问 ord 参数。

如何解决这个问题?

首先,更喜欢使用 Ordering 类型类而不是隐式转换为 Ordered,例如

case class Node[K, V](...)(implicit ord: Ordering[K])

或更短,使用上下文绑定语法:

case class Node[K: Ordering, V](...)

那么,如果你想保留你的默认值,你可能不得不使用重载的 apply 方法而不是默认参数值:

case class WBTreeSet[K: Ordering](tree: Tree[K, Nothing])
object WBTreeSet {
  def apply[K: Ordering](): WBTreeSet[K] = WBTreeSet[K](Tree[K,Nothing]())
}