【问题标题】:No implicit view available from K => Ordered[K]. Error occurred in an application involving default argumentsK => Ordered[K] 没有可用的隐式视图。涉及默认参数的应用程序发生错误
【发布时间】:2018-05-26 13:18:03
【问题描述】:

我正在尝试在 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,我已经搜索了很多类似的问题,但是我仍然无法解决这个问题。有没有办法在不改变类结构的情况下解决这个问题,或者我应该用另一种方式来解决这个问题?

【问题讨论】:

    标签: scala class generics case implicit


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      我想您希望将 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]())
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-11
        • 1970-01-01
        • 2013-10-04
        相关资源
        最近更新 更多