这个 flatMap 代码背后的魔力是什么?
What's the magic behind this flatMap code?
我正在学习 Scala 并在下面的代码中使用 flatMap
(摘自 filter with flatmap or collect)
我有
list flatMap {
case st: String => Some(st)
case _ => None
}
它适用于 List[Any]
并产生 List[String]
scala> List(1, "A") flatMap {
| case st: String => Some(st)
| case _ => None
| }
res21: List[String] = List(A)
现在我对这里的types
感到困惑。正如我所想,flatMap
适用于某些类型的 monad
,它作为 M[M[A]] -> M[A]
.
的转换
下面的代码很容易理解,
def flatten(ls: List[Any]): List[Any] = ls flatMap {
case ms: List[_] => flatten(ms)
case e => List(e)
}
因为两种情况 return 和 List[Any]
仍然是相同类型的 ls: List[Any]
.
但是为什么 Some[String]
和 None
在 List[Any]
的 flatMap
中是可以接受的?
此外,似乎 None
被完全忽略,而不是被视为一个重要的值?我在想可能有一些压缩步骤可以摆脱这些值,比如:
[1,2,3].concat([,,2,2])
// => (6) [1, 2, 3, empty × 2, 2]
[1,2,3].concat([,,4]).filter(Boolean)
// => (4) [1,2,3,4]
谁能解释一下这些?谢谢!!!
As I thought, flatMap works on some kinds of monad which works as a transformation from M[M[A]] -> M[A].
Scala flatMap
更通用(有些人不喜欢)。
如果您查看它们之间的 documentation, it's enough for the function passed to List#flatMap
to return GenTraversableOnce[SomeType]
, not List[SomeType]
. And even though Option
doesn't extend GenTraversableOnce
, there is an implicit conversion,它会在此处应用。
Besides, it seems like None is completely ignored rather then treated as a serious value ?
None
对应空集合,Some(x)
对应单元素集合。所以你有例如
Some(1) ++ Some(2) ++ None ++ Some(3) ==
List(1) ++ List(2) ++ List() ++ List(3) ==
List(1,2,3)
或者,按照您的说法,您没有 [1,2,3,,,4]
(这没有意义),但是 [[1],[2],[3],[],[],[4]]
.
flatMap
不限于相同类型的嵌套集合。传递给 flatMap
的函数返回的值可以是任何集合类型。 flatMap
将获取该集合中的每个元素并将其附加到结果集合。 Option[T]
的工作方式类似于 0 或 1 个元素的集合,因此 flatMap
的工作方式与 List
、Vector
、Array
或其他集合的工作方式相同。
但是在这种特定情况下,您实际上会使用 collect
而不是 flatMap
:
list.collect{ case s: String => s }
我正在学习 Scala 并在下面的代码中使用 flatMap (摘自 filter with flatmap or collect)
我有
list flatMap {
case st: String => Some(st)
case _ => None
}
它适用于 List[Any]
并产生 List[String]
scala> List(1, "A") flatMap {
| case st: String => Some(st)
| case _ => None
| }
res21: List[String] = List(A)
现在我对这里的types
感到困惑。正如我所想,flatMap
适用于某些类型的 monad
,它作为 M[M[A]] -> M[A]
.
下面的代码很容易理解,
def flatten(ls: List[Any]): List[Any] = ls flatMap {
case ms: List[_] => flatten(ms)
case e => List(e)
}
因为两种情况 return 和 List[Any]
仍然是相同类型的 ls: List[Any]
.
但是为什么 Some[String]
和 None
在 List[Any]
的 flatMap
中是可以接受的?
此外,似乎 None
被完全忽略,而不是被视为一个重要的值?我在想可能有一些压缩步骤可以摆脱这些值,比如:
[1,2,3].concat([,,2,2])
// => (6) [1, 2, 3, empty × 2, 2]
[1,2,3].concat([,,4]).filter(Boolean)
// => (4) [1,2,3,4]
谁能解释一下这些?谢谢!!!
As I thought, flatMap works on some kinds of monad which works as a transformation from M[M[A]] -> M[A].
Scala flatMap
更通用(有些人不喜欢)。
如果您查看它们之间的 documentation, it's enough for the function passed to List#flatMap
to return GenTraversableOnce[SomeType]
, not List[SomeType]
. And even though Option
doesn't extend GenTraversableOnce
, there is an implicit conversion,它会在此处应用。
Besides, it seems like None is completely ignored rather then treated as a serious value ?
None
对应空集合,Some(x)
对应单元素集合。所以你有例如
Some(1) ++ Some(2) ++ None ++ Some(3) ==
List(1) ++ List(2) ++ List() ++ List(3) ==
List(1,2,3)
或者,按照您的说法,您没有 [1,2,3,,,4]
(这没有意义),但是 [[1],[2],[3],[],[],[4]]
.
flatMap
不限于相同类型的嵌套集合。传递给 flatMap
的函数返回的值可以是任何集合类型。 flatMap
将获取该集合中的每个元素并将其附加到结果集合。 Option[T]
的工作方式类似于 0 或 1 个元素的集合,因此 flatMap
的工作方式与 List
、Vector
、Array
或其他集合的工作方式相同。
但是在这种特定情况下,您实际上会使用 collect
而不是 flatMap
:
list.collect{ case s: String => s }