Несоответствие типа Scala, ожидаемое: список [двойной], фактическое: список [любой]

#scala #generics #types

#scala #дженерики #типы

Вопрос:

 object lab3zad4 extends App{


val l1 = List(2.0, -1.6, 3.2, 5.4, -8.4)
val l2 = List(3.3, -3.1, 3.2, -4.1, -0.4, 5.5)
val wyn = max(l1,l2,Nil).toString

wyn.foreach(println)


def max(l1: List[Double], l2: List[Double], wyn:List[Double]) : List[Double] = {
 if(l1.isEmpty)
   wyn ::: l2
 if(l2.isEmpty)
   wyn ::: l1
// if(l1.nonEmpty amp;amp; l2.nonEmpty)
  max(l1.tail,l2.tail, wyn :: help(l1.head,l2.head) :: Nil)


def help(x:Double, y:Double): Double = {
 if(x >= y)
   x
 else
   y

}
}
}
  

Несоответствие, похоже, вызвано этой строкой

  max(l1.tail,l2.tail, wyn :: help(l1.head,l2.head) :: Nil) 
  

Когда я удаляю Nil из этой строки, проблема, похоже, исчезает, но я не могу использовать :: для создания нового списка.
Что я делаю не так?
Спасибо за вашу помощь

Ответ №1:

  1. Конечный оператор (выражение) метода — это то, что он возвращает. Так что переходите help() к началу max() , а не к низу.
  2. Используйте else , чтобы превратить эти if проверки в один оператор if (..) else if (..) else
  3. :: используется для добавления элемента в начало a List . Если вам нужно добавить элемент в конец List использования : (очень неэффективно для a List ).
 else max(l1.tail,l2.tail, wyn :  help(l1.head,l2.head))
  
  1. Если вы превратите результат max(l1,l2,Nil) в a String , вы не захотите foreach(println) его переопределять. Это будет println каждый символ String .

Комментарии:

1. Я использовал wyn.foreach(print) для распечатки результата

2. println(wyn) короче, понятнее и эффективнее.

3. Почему? это лучше?

4. "abcde".foreach(print) вызывает print() метод 5 раз, по одному разу для каждого символа String , тогда println("abcde") println() как метод вызывается только один раз.

Ответ №2:

Вы обращаетесь Double к String здесь:

 val wyn = max(l1,l2,Nil).toString
  

затем вы пытаетесь добавить его к List[Double]

 //                               List[Nothing]
//                                   /
//
//         ------ List[Double] --------
//         /                        /
//  ---------- List[Any] --------------
//  /                               /
    wyn :: help(l1.head,l2.head) :: Nil
// String         Double            Nil
  

таким образом, Scala должна определить тип результата, который будет List[Any] , в то время max как функция ожидает List[Double] .

Короче говоря, не вызывайте toString wyn .