我希望获得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]
?发生了什么事?
答案 0 :(得分:2)
x.map(ix => y.map(iy => ix * iy)).flatten
根据Option[Int]
和x
的值返回y
,即如果x
或y
为None
值为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]。