Выражение типа B => List [B] не соответствует ожидаемому типу List [Int] при обращении списка в Scala - PullRequest
0 голосов
/ 16 января 2019

Работа над функцией для обращения к списку в Scala с использованием функции foldLeft:

def reverseWithFold(ls: List[Int]): List[Int] =
        ls.foldLeft(List[Int]())((c, _) => _:::c)

он получил ошибки компиляции: Expression of type List[B_] => List[Int] doesn’t comforrm to expected type List[Int] (PS: я знаю, что мое решение не верное)

Могу я узнать, что это значит? В _:::c здесь _ представляет c в (c, _), а c - это List[Int] тип, поэтому, на мой взгляд, _:::c должно быть объединением двух List[Int]. Он должен соответствовать ожидаемому типу, верно?

Ответы [ 3 ]

0 голосов
/ 16 января 2019

Видите, вы можете написать как List(1,2,3).reduce((x, y) => x + y) или List(1,2,3).reduce(_ + _). Здесь (x, y) => x + y и _ + _ - функции, первая более очевидная, а вторая - функция, где каждое подчеркивание заменяется одним из параметров.

То, что вы делаете здесь, (c, _) => _:::c пытается объединить оба. Но, на самом деле, вы просто говорите компилятору scala:

  1. У меня есть функция двух агентов: c, а другой сбрасывается.
  2. Эта функция возвращает функцию без указанного типа. (Пример: (Int, Int) => (Int => Int) = (a: Int, _) => _ * 2)

Что вы можете сделать здесь, это

переписать, используя только подчеркивание:

ls.foldLeft(List.empty[Int])(_.::(_))

или переписать, не отбрасывая:

ls.foldLeft(List.empty[Int])((acc, cur) => cur :: acc)
0 голосов
/ 16 января 2019

Подчеркивания не являются допустимыми именами переменных, они используются для игнорирования переменных. Два подчеркивания в (c, _) и _ ::: c не связаны.

  • (c, _) => { ... } полностью игнорирует второй параметр, он пропал.
  • _ ::: c является сокращением для лямбда-выражения x => x ::: c, которое ожидает x, который является List[B_] для некоторого неизвестного типа B_, который не может быть выведен, потому что он не ожидается, и его нигде нет найти в вашем коде.

Если вы хотите добавить второй аргумент к первому, вам нужно написать что-то вроде

ls.foldLeft(List.empty[Int])((c, x) => x :: c)

или даже

ls.foldLeft(List.empty[Int])(_.::(_))
0 голосов
/ 16 января 2019
  • ls - список типа List[Int]
  • foldLeft - Создать что-то новое из Int элементов ls.
  • List[Int]()- Это что-то новое будет другим List[Int].Начните с пустого.
  • (c, _) - С каждым шагом получайте построенный List, мы назовем его c и Int из ls, но недать ему имя (т.е. выбросить его).
  • _:::c - Попробуйте объединить 2 списка вместе.Одним из них является список c, который мы создаем, а другим ... ничего.Это не List или Int.Это неназванный параметр, но у нас его нет.Из 2 полученных параметров один был назван c, а другой был отброшен.

Вот один из способов исправить это: (c, n) => List(n):::c (объединить 2 списка вместе)

Вотлучший способ исправить это: (c, n) => n::c (добавить новый элемент в начало этого списка)

Используя неназванные параметры: ls.foldLeft(List[Int]())(_.::(_))

...