gpt4 book ai didi

scala - 如何将 F[A\/B] 拆分为 (F[A], F[B])

转载 作者:行者123 更新时间:2023-12-04 06:20:34 26 4
gpt4 key购买 nike

我偶尔会碰到这样的代码:

val things : List[A \/ B] = ???
val (as, bs) : (List[A], List[B]) = ??? //insert something to do this

或者在我目前的情况下我想要 Map[A, B \/ C] => (Map[A, B], Map[A, C])
在一般情况下,是否有一种很好的方法可以做到这一点 F[A \/ B]对 F 有适当的限制?它看起来有点像 Unzip 主题的变体。

最佳答案

以下是我们如何处理/以及任何和验证,不仅适用于列表,还适用于其他可折叠的。

object Uncozip {
implicit val wtf = language.higherKinds

// Typeclass which covers sum types such as \/, Either, Validation
trait Sum2[F[_, _]] {
def cata[A, B, X](a: A ⇒ X, b: B ⇒ X)(fab: F[A, B]): X
}

implicit val sumEither: Sum2[Either] = new Sum2[Either] {
def cata[A, B, X](a: A ⇒ X, b: B ⇒ X)(fab: Either[A, B]): X = {
fab match {
case Left(l) ⇒ a(l)
case Right(r) ⇒ b(r)
}
}
}

implicit val sumEitherz: Sum2[\/] = new Sum2[\/] {
def cata[A, B, X](a: A ⇒ X, b: B ⇒ X)(fab: A \/ B): X = {
fab.fold(a(_), b(_))
}
}

implicit val sumValidation: Sum2[Validation] = new Sum2[Validation] {
def cata[A, B, X](a: A ⇒ X, b: B ⇒ X)(fab: A Validation B): X = {
fab.fold(a(_), b(_))
}
}

abstract class Uncozips[F[_], G[_, _], A, B](fab: F[G[A, B]]) {
def uncozip: (F[A], F[B])
}

implicit def uncozip[F[_]: Foldable, G[_, _], A, B](fab: F[G[A, B]])(implicit g: Sum2[G], mfa: ApplicativePlus[F], mfb: ApplicativePlus[F]): Uncozips[F, G, A, B] = new Uncozips[F, G, A, B](fab) {
def uncozip = {
implicitly[Foldable[F]].foldRight[G[A, B], (F[A], F[B])](fab, (mfa.empty, mfb.empty)) { (l, r) ⇒
g.cata[A, B, (F[A], F[B])]({ (a: A) ⇒ (mfa.plus(mfa.point(a), r._1), r._2) },
{ (b: B) ⇒ (r._1, mfa.plus(mfa.point(b), r._2)) })(l)
}
}
}
}

关于scala - 如何将 F[A\/B] 拆分为 (F[A], F[B]),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16816536/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com