在折叠函数中展平Some(选项)后输入错误匹配

时间:2015-05-26 05:56:41

标签: scala

我希望获得List[Option[Int]]的产品,并将其展平为Option[Int]

List(Some(2), Some(3), Some(5)).foldLeft(Some(1)) { (x, y) =>

  // err
  x.map(ix => y.map(iy => ix * iy)).flatten

  //   // workaround
  //   x.map(ix => y.map(iy => ix * iy)).flatten match {
  //    case Some(acc) => Some(acc)
  //     case _ => Some(0)
  //   }

}

错误的详细信息:

polymorphic expression cannot be instantiated to expected type;
[error]  found   : [B]Option[B]
[error]  required: Some[Int]
[error]       x.map(ix => y.map(iy => ix * iy)).flatten 
[error]  
flatten中的

foldLeft未返回Some[Int]?发生了什么事?

3 个答案:

答案 0 :(得分:2)

x.map(ix => y.map(iy => ix * iy)).flatten

根据Option[Int]x的值返回y,即如果xyNone值为None,否则为Some[Int]

在fold语句中,种子值为Some(1),其类型为Some[Int].编译器需要与fold语句的结果相同的类型。但是fold语句的表达式的结果值是Option[Int]。因此,错误,所需类型为种子值的Some[Int],但编译器从折叠表达式中找到Option[Int]

任何其他答案都有效。表达式的壁橱只是将种子值从Option(1)更改为Some(1),以便fold语句中种子值和类型的类型匹配,如

List(Some(2), Some(3), Some(5)).foldLeft(Option(1)) { (x, y) => ....

答案 1 :(得分:1)

如果您的列表实际上是$_SESSION,那么对于一个工作示例,您需要声明它们。如果因为我不确定,有人可以准确地说明原因,那将是很棒的。

List[Option[Int]]

但请注意,如果选项列表中的任何元素为val xs = List(Option(2), Option(3), Option(5)) xs.reduceRight((x, b) => x.flatMap(y => b.map(z => y * z))) // res0: Option[Int] = Some(30) ,那么评估将"短路"并返回None。如果您不想要这个,那么我相信您需要查看来自None的一些解决方案,例如应用函子,这里有一些讨论Summing a List of Options with Applicative Functors

答案 2 :(得分:0)

这有效且更简单:

List(Some(2), Some(3), Some(5)).flatten.foldLeft(1) { (x, y) => x * y}

Flattten删除Nones并为你提供List [Int]。