![](/img/trans.png)
[英]Type class for uniting unrelated failure cases in my Scalaz disjunctions
[英]Partition a sequence of disjunctions in Scalaz
使用Scalaz將Seq[A \\/ B]
划分為(Seq[A], Seq[B])
的最佳方法是什么?
有一種方法,包括: separate
定義在MonadPlus。 這個類型類是Monad和PlusEmpty(廣義Monoid)的組合。 所以你需要為Seq
定義實例:
1)MonadPlus [Seq]
implicit val seqmp = new MonadPlus[Seq] {
def plus[A](a: Seq[A], b: => Seq[A]): Seq[A] = a ++ b
def empty[A]: Seq[A] = Seq.empty[A]
def point[A](a: => A): Seq[A] = Seq(a)
def bind[A, B](fa: Seq[A])(f: (A) => Seq[B]): Seq[B] = fa.flatMap(f)
}
Seq已經是monadic,所以point
和bind
很容易, empty
, plus
是monoid操作而Seq
是一個免費的monoid
2)雙折[\\ /]
implicit val bife = new Bifoldable[\/] {
def bifoldMap[A, B, M](fa: \/[A, B])(f: (A) => M)(g: (B) => M)(implicit F: Monoid[M]): M = fa match {
case \/-(r) => g(r)
case -\/(l) => f(l)
}
def bifoldRight[A, B, C](fa: \/[A, B], z: => C)(f: (A, => C) => C)(g: (B, => C) => C): C = fa match {
case \/-(r) => g(r, z)
case -\/(l) => f(l, z)
}
}
也很容易,標准折疊,但對於具有兩個參數的類型構造函數。
現在您可以單獨使用:
val seq: Seq[String \/ Int] = List(\/-(10), -\/("wrong"), \/-(22), \/-(1), -\/("exception"))
scala> seq.separate
res2: (Seq[String], Seq[Int]) = (List(wrong, number exception),List(10, 22, 1))
更新
由於吉田健二 ,有是一個Bitraverse [\\ /],所以你只需要MonadPlus。
使用foldLeft
的簡單解決方案:
seq.foldLeft((Seq.empty[String], Seq.empty[Int])){ case ((as, ai), either) =>
either match {
case \/-(r) => (as, ai :+ r)
case -\/(l) => (as :+ l, ai)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.