用 def 方法和 val 函数展平 Vs flatMap
flatten Vs flatMap with def method and val function
flatten Vs flatMap with def method and val function:
我定义了一个名为 toInt:
的 def 方法
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))
现在我在函数中使用 val 定义了相同的 toInt 功能(如在 def 方法中)"tooInt":
val tooInt: String => Option[Int] = s => {
try {
Some(Integer.parseInt(s.trim))
} catch {
case c: Exception => None
}
}
这适用于展平但不适用于 flatMap,如下所示:
//using map and flatten
println(q.map(tooInt).flatten)
//using flatMap // this has error
**println(q.flatMap(tooInt))**
你能帮我理解一下吗?
此致,
基兰
您需要稍微帮助编译器进行扩展才能使其工作:
q.flatMap(s => tooInt(s))
这一切都归结为我们在 Option.scala
中定义了一个隐含的 option2Iterable
。当您首先 map
然后 flatten
时,Option[Int]
已经在范围内并且可以应用隐式。但是当你 flatMap
时,编译器必须首先将 tooInt
扩展为 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]());
flatten Vs flatMap with def method and val function:
我定义了一个名为 toInt:
的 def 方法 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))
现在我在函数中使用 val 定义了相同的 toInt 功能(如在 def 方法中)"tooInt":
val tooInt: String => Option[Int] = s => {
try {
Some(Integer.parseInt(s.trim))
} catch {
case c: Exception => None
}
}
这适用于展平但不适用于 flatMap,如下所示:
//using map and flatten
println(q.map(tooInt).flatten)
//using flatMap // this has error
**println(q.flatMap(tooInt))**
你能帮我理解一下吗?
此致, 基兰
您需要稍微帮助编译器进行扩展才能使其工作:
q.flatMap(s => tooInt(s))
这一切都归结为我们在 Option.scala
中定义了一个隐含的 option2Iterable
。当您首先 map
然后 flatten
时,Option[Int]
已经在范围内并且可以应用隐式。但是当你 flatMap
时,编译器必须首先将 tooInt
扩展为 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]());