在Scalaz中,将Future[List[Option[List[Double]]]]转换为Future[Option[List[List[Double]]]]

3

我想要将一个 List [Option [List [Double]]] 转换为一个 Option [List [List [Double]]],如果其中一个选项失败(封装在 Future 中),则返回 None。通常我应该能够使用 Scalaz 库中的.sequence。但是当出现以下问题时:

val matrix = for {
  listOfOptions <- futureListOfOptions
  optionOfList <- listOfOptions.sequence
} yield optionOfList

matrix: 未来[无]
listOfOptions: scala.List [Option [scala.List [Double]]]
optionOfList: 任何

我做错了什么?


2
我哪里做错了? -- 我认为最大的问题是有像Future[List[Option[List[Double]]]这样的类型,你最好把它们展平。 - dveim
在我的情况下,如果一个选项失败,我希望它返回None,但是如果我展开它,我就没有了。我之所以会有这样的“混乱”,是因为它来自于Map的值,这些值的类型为Future[Option[List[Double]]](针对服务器向量的查询,因此需要使用future)。 - DennisVDB
可能是你的IDE出了问题?尝试在val声明中输入matrix。这应该会有所帮助。 - C4stor
这没有意义,"如果一个选项失败"? - Rhys Bradbury
你有哪些类型的东西和你所期望的 matrix 类型? - Rhys Bradbury
3个回答

2

将Future[List[Option[List[Double]]]]转换为Future[List[List[Double]]]。

val x: Future[List[Option[List[Double]]]
val y: Future[List[List[Double]]] = x.map(_.flatten)

为什么需要将其包装在选项中?
只需映射列表,如果它没有元素,则不会执行任何操作。


2

你可能缺少了一些导入,或者手动推断类型时只使用了sequence。如果你希望编译器为你尝试,请使用sequenceU

以下代码对我有效:

val start: List[Option[List[Double]]] = ???
  import scalaz.std.option.optionInstance
  import scalaz.std.list.listInstance
  import scalaz.syntax.traverse._

  val end: Option[List[List[Double]]] = start.sequenceU

完整示例:

  val fstart: Future[List[Option[List[Double]]]] = ???
  import scalaz.std.scalaFuture.futureInstance

  val matrix = for {
    lo ← fstart
    ol = lo.sequenceU
  } yield ol

-1

你的意思是像下面这样吗?

val x:List[Option[List[Double]]] = List(Some(List(1.0)),Some(List(2.0)),None)
val y:Option[List[List[Double]]] = {
      val k = x.filter(m => m.isDefined).map(m => m.get)
      if (k.length>0) 
        Some(k)
      else 
        None
}

val k = x.filter(m => m.isDefined).map(m => m.get) 是不好的。 - Rhys Bradbury

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接