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

Den*_*VDB 6 scala list either scalaz

我正在玩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)
    })
}
Run Code Online (Sandbox Code Playgroud)

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

Ven*_*Ven 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])
Run Code Online (Sandbox Code Playgroud)

这基本上是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))
Run Code Online (Sandbox Code Playgroud)

  • 导入`scalaz.Scalaz._`之后. (2认同)