LINUX.ORG.RU

Типы параметров лямбды в Scala

 


0

2

Смотрю тут курс Scala на coursera и вот на что наткнулся:

вот такая штука - работает:

import collection.mutable.HashMap
List('a', 'a', 'b', 'c', 'c', 'c').foldLeft(scala.collection.mutable.HashMap[Char, Int]().withDefaultValue(0))(
  (r: scala.collection.mutable.Map[Char, Int], v: Char) => { r.put(v, r(v) + 1); r }
)

а вот такая - нет:

import collection.mutable.HashMap
List('a', 'a', 'b', 'c', 'c', 'c').foldLeft(HashMap[Char, Int]().withDefaultValue(0))(
  (r: HashMap[Char, Int], v: Char) => { r.put(v, r(v) + 1); r }
)

говорит про лябмду следующее:

[error]  found   : (scala.collection.mutable.HashMap[Char,Int], Char) => scala.collection.mutable.HashMap[Char,Int]
[error]  required: (scala.collection.mutable.Map[Char,Int], Char) => scala.collection.mutable.Map[Char,Int]
[error]       (r: scala.collection.mutable.HashMap[Char, Int], v: Char) => { r.put(v, r(v) + 1); r }

почему так?

import collection.mutable.HashMap
import collection.mutable.Map

object Main {
    def main(args: Array[String]) {
      val list  = List('a', 'a', 'b', 'c', 'c', 'c').foldLeft(HashMap[Char, Int]().withDefaultValue(0))(
        (r: Map[Char, Int], v: Char) => { r.put(v, r(v) + 1); r }
      )
      println(list)
    }
}

а еще можно так:

import collection.mutable

object Main {
    def main(args: Array[String]) {
      val list  = List('a', 'a', 'b', 'c', 'c', 'c').foldLeft(mutable.HashMap[Char, Int]().withDefaultValue(0))(
        (r: mutable.Map[Char, Int], v: Char) => { r.put(v, r(v) + 1); r }
      )
      println(list)
    }
}
stevejobs ★★★★☆
()
Ответ на: комментарий от stevejobs

Боюсь я не совсем понял твой коммент: моя идея была в том, что лямбда, которая использует 1 параметр типа HashMap и возвращает значение типа HashMap - вызывает ошибку компиляции, хотя по идее - не должна, ибо в доке написано такое определение:

foldLeft[B](z: B)(f: (B, A) ⇒ B): B

то есть вот тот самый тип B у меня - HashMap, а не один из его trait-ов Map.

В комменте ты просто обернул все в Object Main и println добавил. В чем идея коммента была?

Goganchic ★★
() автор топика
Ответ на: комментарий от Goganchic

Вероятно в том, что отличие кода длиной в 25 символов находится гораздо быстрее, чем отличие в 4 символа. Учитывай это обстоятельство при написании вопроса.

anonymous
()
Ответ на: комментарий от Goganchic

ты как-то избирательно прочитал коммент xD

идея в том, что я предложил добавить в импорты «collection.mutable.Map». Чтобы он запись «r: Map[Char, Int]» начал интерпретировать через mutable.Map. И таким образом перестал выдавать ошибку компиляции.

иначе говоря, мой код компилируется и работает, а твой - нет.

и чтобы не зашквариться, всегда использовать префикс mutable для мутабельных типов. Т.е. чтобы запись «HashMap» всегда означала только немутабельный хэшмап, а «mutable.HashMap» мутабельный.

а в object Main я всё обернул, потому что как я твой код буду выполнять, в уме что ли? :3

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от Goganchic

Кажется понял, что ты как бы хотел сказать. «Почему я должен писать, r: mutable.Map[Char, Int], чего он сам не догадался что мне именно мутабельная мапа нужна!»

А он сам вполне себе догадался. Только ты полез ему руками указывать, и он тебе поверил. Вот что будет, если не вмешиваться:

import collection.mutable.HashMap

object Main {
  def main(args: Array[String]) {
    val list  = List('a', 'a', 'b', 'c', 'c', 'c').foldLeft(HashMap[Char, Int]().withDefaultValue(0))(
      (r, v) => { r.put(v, r(v) + 1); r }
    )
    println(list)
  }
}
stevejobs ★★★★☆
()

потому что withDefault возвращает Map, а не HashMap:

scala> scala.collection.mutable.HashMap[Char, Int]().withDefaultValue(0)
res0: scala.collection.mutable.Map[Char,Int] = Map()
maxcom ★★★★★
()
Ответ на: комментарий от maxcom

это у вас в предефе оно так называется, а приличные люди и так знают.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.