Bestest
Bestest

Reputation: 13

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

I'm trying to implement a set based on a weight-based tree in Scala. I have the following class hierarchy:

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

Classes get Ordered[K] implicitly so that I can compare elements of type K and build the tree.

When I try to compile the code, I get the following errors:

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

When I delete the default value for tree in WBTreeSet, the code compiles.

I'm using Scala for the first time and I have already searched a lot of similar problems, however I still cannot resolve this issue. Is there any way to fix this without changing the structure of classes or should I do it another way?

Upvotes: 1

Views: 499

Answers (2)

ghik
ghik

Reputation: 10764

I suppose you expect the implicit ord parameter of WBTreeSet to be passed to default value of tree parameter. Unfortunately, this will not work because in Scala, default parameter values cannot refer to other parameter values in the same parameter list or in subsequent parameter lists, e.g.

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

That, plus the fact that implicit parameters can only be passed in the last parameter list means that your tree param default value cannot access ord param.

How to work around this?

First, prefer using Ordering typeclass instead of implicit conversion to Ordered, e.g.

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

or shorter, using context bound syntax:

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

Then, if you want to keep your default value, you probably have to use overloaded apply method instead of default parameter value:

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

Upvotes: 1

Dmytro Mitin
Dmytro Mitin

Reputation: 51658

Try overloaded apply methods:

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

Upvotes: 0

Related Questions