未来[List [Error \ / Double]]到Scala中的Future [[List [Error] \ / List [Double]]

问题描述 投票:6回答:2

我正在玩Scala(z)来学习函数式编程。

我有一个Future[List[Error \/ Double]]类型的值,并希望将其转换为类型为Future[[List[Error] \/ List[Double]]的东西。

目标是对左派和权利进行分组。

我目前有以下内容:

val foo: Future[List[Error] \/ List[Double]] = {
  for {
    results <- resultsF
  } yield
    results.foldLeft(\/[List[Error], List[Double]])({
      case (acc, v) if v.isRight => v :: \/-(acc)
      case (acc, v) if v.isLeft => v :: -\/(acc)
    })
}

但是,我在::上得到一个错误,这是因为我的累加器不是一个列表(来自外部)\/[List[Error], List[Double]]。应该怎么做?

list scala scalaz either
2个回答
5
投票

Haskell中的这个函数将是partitionEithers[Either a b] -> ([a], [b])

(你实际上并不想要Either [a] [b],这真的没有意义。我猜你想要这个功能,因为你的描述中的文字......)

Scalaz没有原样。但是,它有一个更普遍的separate

/** Generalized version of Haskell's `partitionEithers` */
def separate[G[_, _], A, B](value: F[G[A, B]])(implicit G: Bifoldable[G]): (F[A], F[B])

这基本上是Bifoldable g, MonadPlus f => f (g a b) -> (f a), (f b)。具体来说:[Either a b] -> ([a], [b])。您可以简单地在列表中调用它(g = \/(或Either),f = List)。

在行动:

scala> import scalaz._, Scalaz._
scala> List(\/-(3), -\/("a")).separate
res1: (List[String], List[Int]) = (List(a),List(3))

0
投票

严格来说,您可以实现此类功能,例如,如何应用此列表:

-\/(A) :: \/-(B) :: Nil

假设输入列表全部保留或完全正确,您可以查看第一个,并决定如何处理遗骸:

val foo: Future[List[Error] \/ List[Double]] =
  resultsF.map(resultsF.head match {
    case -\/(_) => { _.left }
    case \/-(_) => { _.right }
  })

假设您想要分组左侧和权限,返回的单个折叠(List [L],List [R])完美地工作:

val foo[L,R]: Future[(List[L], List[R])] =
  resultsF.foldr((Nil, Nil)){ (s, v) =>
    case -\/(l) => (l :: s._1, s._2)
    case \/-(r) => (s._1, r :: s._2)
  }
© www.soinside.com 2019 - 2024. All rights reserved.