Неявное представление не доступно из K => Упорядочено [K].Произошла ошибка в приложении с аргументами по умолчанию - PullRequest
0 голосов
/ 26 мая 2018

Я пытаюсь реализовать набор на основе весового дерева в 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]) {

Когда я удаляю значение по умолчанию для tree в WBTreeSet, код компилируется.

Я впервые использую Scala и уже искал много похожих проблем, однако до сих пор не могу решить эту проблему.Есть ли способ исправить это без изменения структуры классов или я должен сделать это по-другому?

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Полагаю, вы ожидаете, что неявный параметр 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 param не может получить доступ к ord param.

Как обойти это?

Во-первых, предпочтительнее использовать 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]())
}
0 голосов
/ 26 мая 2018

Попробуйте перегрузить 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]())
}
...