首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将F[[A,B]]转换为[F[A],F[B]]

如何将F[[A,B]]转换为[F[A],F[B]]
EN

Stack Overflow用户
提问于 2019-07-12 18:57:50
回答 1查看 255关注 0票数 2

一些背景:猫中有一个.separate函数,它允许我从F[Either[A, B]]中提取元组(F[A], F[B])。考虑到这一点,我们可以很容易地构造Either[F[A], F[B]] --假设我们可以检查F是否为空(单样体可以吗?)列表的代码可能如下所示

代码语言:javascript
复制
val l: List[Either[_, _]] = ???
l.separate match {
  case (Nil, rights) => Right(rights)
  case (lefts, _) => Left(lefts)
}

但这似乎是一个更普遍的概念,但我不太清楚这是什么。它看起来有点像.sequence,但我们的G有两个漏洞。也就是说,我们需要一个转换F[G[A, B]] -> G[F[A], F[B]]

你是否知道是否存在这样的概念,或者如何在没有pattern matching / if statements / Either.cond的猫身上实现这个目标?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-12 21:33:16

您可以使用AlternativeTraverse的组合来尝试。

This special case可以从List推广到任意F

代码语言:javascript
复制
def collectErrors[A, B](xs: List[Either[A, B]]): Either[List[A], List[B]] = {
  xs.traverse(_.left.map(List(_)).toValidated).toEither
}

下面是一张购物清单,上面列出了我们需要做的事情:

  1. 我们需要某种替代List(_)的方法。这通常是Applicative[F].pure(_) (或_.pure[F]),所以我们需要Applicative
  2. 我们需要一个MonoidF[X]上,这样我们就可以在Validated的左边积累错误。幸运的是,有MonoidK[F[_]],它知道如何为任何给定的X生成Monoid[F[X]]
  3. F[_]必须是可遍历的,这样我们才能从F[Validated[F[A], B]]Validated[F[A], F[B]],因此我们需要Traverse

有一个特征Alternative,它是ApplicativeMonoidK的结合。把这一切结合在一起会让你:

代码语言:javascript
复制
  import scala.util.Either
  import cats._
  import cats.syntax.either._
  import cats.syntax.traverse._
  import cats.syntax.applicative._

  def collectErrors[F[_]: Alternative : Traverse, X, Y](xs: F[Either[X, Y]])
  : Either[F[X], F[Y]] = {
    implicit val mon = MonoidK[F].algebra[X]
    xs.traverse(_.left.map(_.pure[F]).toValidated).toEither
  }

现在,这应该适用于ListVectorChain等。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57012653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档