Загадочное несоответствие типов в Scala foldRight

Может кто-нибудь, пожалуйста, скажите мне, что не так с этим определением функции?

def incr[Int](l: List[Int]): List[Int] = 
  l.foldRight(List[Int]())((x,z) => (x+1) :: z)

Компилятор Scala жалуется на несоответствие типов в теле функции, переданной в foldRight:

<console>:8: error: type mismatch;
 found   : Int(1)
 required: String
           l.foldRight(List[Int]())((x,z) => (x+1) :: z)
                                                ^

В чем проблема?


person Bill Barrington    schedule 20.11.2012    source источник


Ответы (2)


С помощью def incr[Int] вы определили произвольный тип с именем Int, который переопределяет существующий. Избавьтесь от параметра типа [Int], и он будет работать нормально, или используйте другое имя, например T.

person Luigi Plinge    schedule 20.11.2012
comment
Та же ошибка: def incr[T](l: List[T]): List[T] = l.foldRight(List[T]())((x,z) => (x+1) :: z) все еще не понимаю (?) - person Bill Barrington; 20.11.2012
comment
Извини, что так туплю, тупой, понял. Спасибо. def incr(l: List[Int]): List[Int] = l.foldRight(List[Int]())((x,z) => (x+1) :: z) - person Bill Barrington; 20.11.2012
comment
@Bill произвольный тип не имеет метода +, поэтому либо тип вашего элемента должен быть Int, либо функция, которую вы передаете foldRight, должна работать с Any. Я не совсем уверен, почему создается именно это сообщение об ошибке, но, вероятно, это как-то связано с тем, что компилятор думает, что + - это метод объединения строк. Было бы неплохо, если бы компилятор выдал вам предупреждение о типах затенения. - person Luigi Plinge; 20.11.2012
comment
Да, я работал над упражнениями в книге (Функциональное программирование в Scala), которую я только что купил, и настолько привык к вводу параметров типа, что на данный момент я ослеп. Я понял свою ошибку, как только выключился на вечер. Расслабленный ум мыслит гораздо яснее... :-) - person Bill Barrington; 20.11.2012

То, что говорит Луиджи, работает для меня. Я не уверен, зачем вам нужен параметр типа, поскольку вы уже указываете ввод как список Int:

def incr(l: List[Int]): List[Int] = l.foldRight(List[Int]())((x,z) => (x+1) :: z)

incr(List(1,2,3))                 //> res0: List[Int] = List(2, 3, 4)

Но с другой стороны и не связанной с фактическим вопросом, если это предполагаемый результат, альтернативным способом может быть:

def incr2(l:List[Int]):List[Int] = l map (_+1)
person Plasty Grove    schedule 20.11.2012