Я использую дерево, определенное здесь ...Попытки создать общую функцию просуммировать элементы дерева
https://gist.github.com/schmmd/1271891
где ...
class Tree[+T]
case object Empty extends Tree[Nothing]
case class Node[T](val elem: T, val left: Tree[T], val right: Tree[T]) extends Tree[T]
Я добавил эту особенность ...
trait sum[T] {
def +(value: T): T
}
и я определил это дерево ...
val a = Node(1, Node(1, Empty, Node(5, Empty, Empty)), Node(2, Node(3, Empty, Empty), Empty))
Тогда я написал эту функцию, чтобы подытожить элементы ...
def sumTree[T <: sum[T]](t: Tree[T]): T = t match {
case Empty => 0
case Node(e, left, right) => e + sumTree(left) + sumTree(right)
}
Вопросы
1) Почему я должен определить черту (предполагая, что я имею правильно определил это), чтобы использовать «+»? Без него компилятор рассматривает это как попытку конкатенации строки.
2) Я не уверен, как обращаться с «пустым». Я хочу обрабатывать «Пусто» как 0 при сопоставлении с образцом, но я не могу из-за общей обработки. Неужели я не могу сделать эту работу с дженериками? Я должен был бы указать тип, который он принимает/возвращает заранее?
Спасибо! Что, если я хочу придерживаться черты? Как использовать нуль/плюс в этом случае? Я получаю сообщение об ошибке, которая не может быть разрешена. – cpd1
Ну, вы можете добавить 'zero' в свой исходный признак, например' trait sum [T] {def zero: T; def + (значение: T): T} ', но это не имеет особого смысла, поскольку оно не связано с текущим представленным значением ... Также тогда ваш метод' sumTree' потребует значения типа 'T' для иметь доступ к «нулю». Или вы пишете 'def sumTree [T <: sum [T]] (t: Tree [T], ноль: T): T'. Поэтому я бы рекомендовал вам придерживаться типа-класса, такого как 'Numeric'. –
ОК спасибо. Кажется немного грязным, чтобы придерживаться этой черты, поэтому я буду работать с Numeric – cpd1