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



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

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]) {

当我删除WBTreeSettree的默认值时,代码将编译。

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

我想您希望将隐式ord参数WBTreeSet传递给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参数。

如何解决这个问题?

首先,更喜欢使用 typeclass 而不是隐式转换为OrderedOrdering,例如

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]())
}

尝试重载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]())
}

最新更新