输入与map和flatMap不匹配

时间:2013-01-29 08:38:54

标签: scala types map

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

我开始创建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中列表的条目上映射一个加法,如下所示:

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会对地图和flatMap都失败吗?

6 个答案:

答案 0 :(得分:6)

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

出现奇怪的错误消息是因为Scala假定,因为Option没有+方法,您正在尝试String连接,但是您必须添加一个OptionString,或StringOption,而您没有,因此出现错误消息。

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

答案 1 :(得分:1)

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

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

正如@ Sepp2k所指出的那样,您也可以使用collect来避免None的默认值

res0 collect {case Some(x) => x + 1 }

答案 2 :(得分:1)

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

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

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

scala> res0.flatMap(_.map(_ + 1))
res2: List[Int] = List(2, 3, 4)

答案 3 :(得分:1)

赋予flatMap的函数以及赋给map的函数都采用列表元素类型的值 - 在本例中为Option[Int]。但是,您的函数_ + 1需要Int,而不是Option[Int],因此在这种情况下,您无法将其用作mapflatMap的参数。此外,赋予flatMap的函数应该返回一个可迭代的¹,但是你的函数会返回一个数字。

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

¹技术上是GenTraversableOnce

答案 4 :(得分:1)

您尝试在e.+(1)中的每个元素e上调用List[Option[Int]],但+不是Option[_]声明的函数。但是,字符串连接是可能的(我假设存在从AnyString的隐式),但是只有当第二个参数也是一个字符串时(不确定为什么隐含了我的假设)这里不考虑。)

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

map(_.map(_ + 1))

答案 5 :(得分:1)

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

地图案例失败,因为map需要一个函数A => B。在您的代码中,A => B确实是Int => Int,因为在您的列表中调用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