选项上的flatmap(GenTraversableOnce)

时间:2016-02-26 14:03:07

标签: scala

这不起作用:

val res = myOption flatMap (value => Seq(value, “blo”))

但是这是的:

val res = myOption.toSeq flatMap (value => Seq(value, “blo”))

您认为flatMap上的Option应该像GenTraversableOnce一样Seq吗? 或者此代码对可读性不利,我应该使用matchmap / getOrElse

修改:我们在for / yield上也遇到了同样的问题。

干杯

2 个答案:

答案 0 :(得分:3)

Option.flatMap返回Option,它与序列“相似”,但不能包含多个元素。如果允许使用函数,则返回Seq,并返回包含多个元素的SeqflatMap的返回值是什么(请记住,它需要成为Option)?

为什么flatMap首先需要返回一个选项?好吧,所有 flatMap实现返回与它们开始时相同的类型。这是有道理的:如果我有一个Option的东西,并想以某种方式转换内容,最常见的用例是我想最终得到另一个Option。如果flatMap给我一个Seq,我会这样做吗? .headOption?这不是一个好主意,因为它可能会默默地丢弃数据。 if(seq.size < 2) seq.headOption else throw ....?嗯,这有点好,但看起来很难看,并且在编译时不可执行。

另一方面,当您需要时将Option转换为Seq非常简单且完全安全:只需执行.toSeq

答案 1 :(得分:3)

flatMap的整体语义是像monadic bind方法一样工作,这意味着它往往具有类似

的签名
[A]this:T[A].flatMap[B](f: A => T[B]): T[B]

有时候(SeqLike)此签名被推广到

[A]this:T[A].flatMap[B](f: A => F[B]): T[B] 

其中F[B]可轻松转换为T[B]

因此,不仅Option,而且concurrent.Futureutil.TryBindOps - scalaz monads的扩展语法具有不接受任何可遍历的方法flatMap ,但只有相同的包装类型。

即。 flatMap更多来自monads世界,而不是来自集合