Scala 中的 Future[List[Error \/ Double]] 到 Future[[List[Error] \/ List[Double]]
Future[List[Error \/ Double]] to Future[[List[Error] \/ List[Double]] in Scala
我正在使用 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]]
。应该怎么做?
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))
严格来说,你可以实现这样的功能,例如,你如何应用这个列表:
-\/(A) :: \/-(B) :: Nil
假设输入列表全左或全右,你可以看第一个,然后决定如何处理剩下的:
val foo: Future[List[Error] \/ List[Double]] =
resultsF.map(resultsF.head match {
case -\/(_) => { _.left }
case \/-(_) => { _.right }
})
假设您想要将左侧和右侧分组,returns (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)
}
我正在使用 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]]
。应该怎么做?
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))
严格来说,你可以实现这样的功能,例如,你如何应用这个列表:
-\/(A) :: \/-(B) :: Nil
假设输入列表全左或全右,你可以看第一个,然后决定如何处理剩下的:
val foo: Future[List[Error] \/ List[Double]] =
resultsF.map(resultsF.head match {
case -\/(_) => { _.left }
case \/-(_) => { _.right }
})
假设您想要将左侧和右侧分组,returns (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)
}