1

在尝试使用 scala 中的选项时,我遇到了这个特殊的问题。

我开始创建一个 List[Option[Int]] 如下:

scala> List(Some(1),Some(2),None,Some(3))
res0: List[Option[Int]] = List(Some(1), Some(2), None, Some(3))

然后我尝试在 res0 中的列表条目上映射 1 的添加,如下所示:

scala> res0 map (_ + 1)

这给了我错误:

<console>:9: error: type mismatch;
 found   : Int(1)
 required: String
              res0 map (_ + 1)
                            ^

然后我尝试对条目进行 flatMapping 的添加,如下所示:

scala> res0 flatMap (_ + 1)

这给了我同样的错误:

<console>:9: error: type mismatch;
 found   : Int(1)
 required: String
              res0 flatMap (_ + 1)
                                ^

但是类似的东西res0.flatMap(r => r)效果很好,结果是:

res9: List[Int] = List(1, 2, 3)

谁能告诉我为什么将条目添加到 1 对 map 和 flatMap 都会失败?

4

6 回答 6

6

您尝试的前两件事失败了,因为您试图将 an 添加Option到 an Int,这是不可能的。

发生奇怪的错误消息是因为 Scala 假设,因为Option没有+方法,您正在尝试String连接,但是您必须将 an 添加Option到 aString或 a添加String到 an Option,并且您都没有这样做,因此错误消息.

在最后一种情况下,您没有尝试添加任何内容,您只是Option按原样返回,因此没有错误消息。

于 2013-01-29T08:55:57.327 回答
1

尝试使用 get 提取值Some[Int]Int允许计算,value + 1即:

res0 map{_.getOrElse(0) + 1}

正如@Sepp2k 所指出的,您也可以使用 acollect来避免默认为None

res0 collect {case Some(x) => x + 1 }
于 2013-01-29T08:47:54.610 回答
1

要增加所有不是的值None,您还需要映射Option列表的每个元素,如下所示:

scala> res0.map(_.map(_ + 1))
res1: List[Option[Int]] = List(Some(2), Some(3), None, Some(4))

如果你想过滤掉Nones,你确实会使用 a flatMap

scala> res0.flatMap(_.map(_ + 1))
res2: List[Int] = List(2, 3, 4)
于 2013-01-29T08:53:34.233 回答
1

给定的函数flatMap和给定的函数都可以map获取列表元素类型的值 - 在这种情况下Option[Int]。但是您的函数_ + 1需要一个Int,而不是,因此在这种情况下Option[Int],您不能将其用作参数。此外,给定的函数应该返回一个可迭代的¹,但您的函数将返回一个数字。mapflatMapflatMap

这将做你想要的:res0 flatMap (_ map (_ + 1))。在这里,给定的函数flatMap接受一个并通过调用选项Option[Int]返回一个。然后获取函数返回的选项并将它们连接起来。Option[Int]mapflatMap

¹ 技术上是一个GenTraversableOnce.

于 2013-01-29T08:53:51.940 回答
1

您尝试在 a 中的每个元素上调用,e.+(1)但不是由 . 声明的函数。然而,字符串连接是可能的(我假设有一个隐含的 from to ),但前提是第二个参数也是一个字符串(不确定为什么这里不考虑我假设的隐含的存在)。eList[Option[Int]]+Option[_]AnyString

您可以通过使用@korefn 建议的默认值来解决这个问题,或者“隐藏”另一个调用之间的区别Some(x),即通过Nonemap

map(_.map(_ + 1))
于 2013-01-29T08:56:11.967 回答
1

它们失败了,因为类型错误并且编译器正确地声明了它。

map 案例失败,因为map需要一个 function A => B。在您的代码中,A => Bis really Int => Intwhich 将不起作用,因为调用map您的列表意味着它A实际上是 Option[Int].

此外,flatMap期望形式的功能A => F[B]。因此,如果您这样做了,您将得到答案res0 flatMap { o => o map { a => a + 1 } }。这基本上是以下内容的扩展:

for {
  element <- res0 // o above
  value <- element // a above
} yield value + 1
于 2013-01-29T09:00:35.237 回答