flatten Vs flatMap с методом def и функцией val

flatten Vs flatMap с методом def и функцией val:

Я определил метод def под названием toInt:

  def toInt(s: String): Option[Int] = {
    try {
      Some(Integer.parseInt(s.trim))
    } catch {
      case e: Exception => None
    }
  }

и этот метод отлично работает как с flatten, так и с flatMap следующим образом:

//using toInt method
val x = 1.to(5).toList
val y = List("a")
val z = x ++ y
val q = z.map(_.toString)

//using map and flatten
println(q.map(toInt).flatten)
//using flatMap
println(q.flatMap(toInt))

теперь я определил ту же функциональность toInt (как в методе def), используя val в функции "tooInt":

val tooInt: String => Option[Int] = s => {
  try {
    Some(Integer.parseInt(s.trim))
  } catch {
    case c: Exception => None
  }
}

это отлично работает с flatten, но не С flatMap как показано ниже:

//using map and flatten
 println(q.map(tooInt).flatten)
 //using flatMap // this has error
 **println(q.flatMap(tooInt))**

не могли бы вы помочь мне понять это?

С Наилучшими Пожеланиями, Киран!--7-->

1 ответов


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

q.flatMap(s => tooInt(s))

все сводится к тому, что у нас есть неявное option2Iterable определена в Option.scala. Когда вы первый map а то flatten на Option[Int] уже находится в области видимости, и неявное может быть применено. Но когда ты ... --9--> компилятор должен сначала расширить tooInt to s => tooInt(s) и затем применить неявное разрешение, но это не работает. Почему это не работает? потому что компилятор выглядит для неявного типа:

pt=(=> String => Option[Int]) => (String => scala.collection.GenTraversableOnce[?])

, которого не существует. Напротив,toInt метод сначала расширяется в тип функции, а затем неявный выполняется поиск Option[Int]:

-- toInt : pt=String => scala.collection.GenTraversableOnce[?] BYVALmode-EXPRmode-POLYmode (site: value r in X)
|    |    |    |    |    |    |-- { ((s: String) => toInt(s)) } : pt=String => scala.collection.GenTraversableOnce[?] BYVALmode-EXPRmode-POLYmode (site: value r in X)
|    |    |    |    |    |    |    |-- ((s: String) => toInt(s)) : pt=String => scala.collection.GenTraversableOnce[?] BYVALmode-EXPRmode-POLYmode (site: value r in X)
|    |    |    |    |    |    |    |    |-- (s: String)Option[Int] : pt=scala.collection.GenTraversableOnce[?] EXPRmode (site: value $anonfun in X)
|    |    |    |    |    |    |    |    |    |-- s : pt=String BYVALmode-EXPRmode (site: value $anonfun in X)
|    |    |    |    |    |    |    |    |    |    \-> String
|    |    |    |    |    |    |    |    |    [search #3] start `(s: String)Option[Int]`, searching for adaptation to pt=Option[Int] => scala.collection.GenTraversableOnce[?] (silent: value $anonfun in X) implicits disabled
|    |    |    |    |    |    |    |    |    [search #3] considering scala.this.Option.option2Iterable

мы также можем видеть это в декомпилированном коде:

val r: scala.collection.immutable.IndexedSeq[Int] = q.flatMap[Int, scala.collection.immutable.IndexedSeq[Int]]({
    {
      final <artifact> def $anonfun$main(s: String): Iterable[Int] = scala.this.Option.option2Iterable[Int](toInt(s));
      ((s: String) => $anonfun$main(s))
    }
  }, immutable.this.IndexedSeq.canBuildFrom[Int]());