Странные ошибки в скалах.найдено: scala. Double требуется Double - PullRequest
0 голосов
/ 02 декабря 2018

У меня есть дерево, в котором хранится список элементов в узлах.Мне нужно написать функцию, которая берет такое дерево и возвращает дерево с суммой элементов в узлах.

Я подумал, что это простая задача, но произошли некоторые ошибки: ошибки

Вот что IntelliJ показывает:

код с ошибкой компилятора

И, наконец, вот мой код:

sealed trait tree[+A]
case object Empty extends tree[Nothing]
case class Node[A](element:A,left:tree[A],right:tree[A]) extends tree[A]

val tr=Node(List(1,2,3),Node(List(3,4,5),Empty,Node(List(2,4,5),Empty,Empty)),Node(List(6,7,8),Empty,Empty))

def transformTree[Double](t:tree[List[Double]]):tree[Double]={
t match{
case Empty => Empty
case Node(l,left,right)=>Node[Double](l.foldLeft(0)((a:Double,b:Double)=>(a+b)),transformTree(left),transformTree(right))
}
}
   transformTree(tr)

У меня естьПонятия не имею, почему он ожидает строку, поэтому, пожалуйста, объясните мне, если можете:)

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018
  1. Имена классов должны начинаться с заглавной буквы.
  2. 0 - это 32-разрядное целое число, вам нужно 0d для 64-разрядных Double с.
  3. Выхочу определить transformTree для Double, а не для произвольного типа, связанного с переменной типа с именем Double.В настоящее время ваша сигнатура функции эквивалентна def transformTree[X](t: Tree[List[X]]): Tree[X], и о X почти ничего не известно, за исключением того, что она является подтипом Any и, таким образом, имеет операцию + для объединения своего строкового представления с другими строками.
  4. Ваш tr должен быть Tree[Double], а не Tree[Int].
  5. Существует sum, нет необходимости fold что-либо.Даже если вы хотите foldLeft, это должно было быть что-то вроде l.foldLeft(0d)(_ + _).

Это компилируется:

sealed trait Tree[+A]
case object Empty extends Tree[Nothing]
case class Node[A](element:A,left:Tree[A],right:Tree[A]) extends Tree[A]

val tr = Node(List(1d,2d,3d),Node(List(3d,4d,5d),Empty,Node(List(2d,4d,5d),Empty,Empty)),Node(List(6d,7d,8d),Empty,Empty))

def transformTree(t: Tree[List[Double]]): Tree[Double] = {
  t match{
    case Empty => Empty
    case Node(l, left, right) => 
      Node[Double](l.sum, transformTree(left), transformTree(right))
  }
}
transformTree(tr)
0 голосов
/ 02 декабря 2018

Ну ... дело в том, что когда вы определяете def, например,

def abc[A](a: A) = ??

Этот A здесь является параметром универсального типа, и этот параметр типа A имеет наивысший приоритет вразрешение типа внутри области действия def.Таким образом, любой другой тип A не будет распознаваться как A в этой области.

Проще говоря, если вы сделаете что-то вроде

def abc[Double](a: Double) = a

Это Double здесьне факт Double, который вы знаете, но это параметр типа, который открыт для пользователя этого def.

И приведенная выше строка эквивалентна,

def abc[A](a: A) = a
// Or
def abc[B](b: B) = b

Thisозначает, что в области действия def transformTree[Double] def эти Double не являются действительными Double, а являются типом переменной, который будет определен при фактическом использовании функции.

И так как выиспользование этого a + b fold, начинающегося с 0, означает, что ваш transform в значительной степени фиксирован.И если вы хотите реализовать это для Double,

sealed trait Tree[+A]
case object Empty extends Tree[Nothing]
case class Node[A](element: A, left: Tree[A], right: Tree[A]) extends Tree[A]

val tr = Node(
  List(1d, 2d, 3d),
  Node(
    List(3d, 4d, 5d),
    Empty,
    Node(
      List(2d, 4d, 5d),
      Empty,
      Empty
    )
  ),
  Node(
    List(6d, 7d, 8d),
    Empty,
    Empty
  )
)

def transformTree(t: Tree[List[Double]]): Tree[Double] = {
  t match {
    case Empty => Empty
    case Node(l, left, right) => Node(
      l.foldLeft(0d)((acc: Double, elem: Double) => (acc + elem)),
      transformTree(left),
      transformTree(right)
    )
  }
}

transformTree(tr)
...