Fold function scala неизменный список - PullRequest
0 голосов
/ 12 апреля 2020

Я создал неизменный список и попытался свернуть его на карту, где каждый элемент сопоставлен с постоянной строкой «ab c». Я делаю это для практики. Пока я это делаю, я получаю ошибку. Я не уверен, почему карта (здесь e1 с изменяемым типом карты) конвертируется в Any.

val l = collection.immutable.List(1,2,3,4)
l.fold (collection.mutable.Map[Int,String]()) ( (e1,e2) => e1 += (e2,"abc") )

l.fold (collection.mutable.Map[Int,String]()) ( (e1,e2) => e1 += (e2,"abc") )
<console>:13: error: value += is not a member of Any
  Expression does not convert to assignment because receiver is not assignable.
       l.fold (collection.mutable.Map[Int,String]()) ( (e1,e2) => e1 += (e2,"abc") )

Ответы [ 2 ]

3 голосов
/ 12 апреля 2020

Здесь как минимум три разных источника проблем:

  1. Map[...] не является супертипом Int, поэтому вы, вероятно, хотите foldLeft, а не fold (действия fold больше похоже на "банановые скобки" , он ожидает, что первый аргумент будет действовать как некий "ноль", а двоичная операция - как некое "дополнение" - это не относится к изменяемым картам и целым числам ).
  2. Двоичная операция должна возвращать что-то , оба для fold и foldLeft. В этом случае вы, вероятно, захотите вернуть измененную карту. Вот почему вам нужен ; m (последнее выражение - это то, что возвращается из замыкания).
  3. m += (k, v) - это не то, что вы думаете. Он пытается вызвать метод += с двумя отдельными аргументами. Что вам нужно, это вызвать его с одной парой. Вместо этого попробуйте m += ((k, v)) (да, эти проблемы с арностью раздражают).

Соберите все вместе:

l.foldLeft(collection.mutable.Map[Int, String]()){ (m, e) => m += ((e, "abc")); m }

Но так как вы все равно используете изменяемую карту:

val l = (1 to 4).toList
val m = collection.mutable.Map[Int, String]()
for (e <- l) m(e) = "abc"

Это выглядит, пожалуй, понятнее, если честно. В foldLeft я бы не ожидал, что карта будет видоизменяться.

2 голосов
/ 12 апреля 2020

Складывание - это объединение последовательности элементов ввода в один элемент вывода. Элементы вывода и ввода должны иметь одинаковые типы в Scala. Вот определение fold:

  def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1

В вашем случае тип A1 равен Int, но элемент вывода (тип суммы) равен mutable.Map. Поэтому, если вы хотите построить Map через итерацию, вы можете использовать foldLeft или любые другие альтернативы, где вы можете использовать разные типы ввода и вывода. Вот определение foldLeft:

def foldLeft[B](z: B)(op: (B, A) => B): B

Решение:

val l = collection.immutable.List(1, 2, 3, 4)
l.foldLeft(collection.immutable.Map.empty[Int, String]) { (e1, e2) =>
  e1 + (e2 -> "abc")
}

Примечание: я не использую mutabe Map

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...