Bifoldable
Формальное определение
Bifoldable
- тип, порождающий два несвязанных Foldable
.
Определение в виде кода на Scala
trait Bifoldable[F[_, _]]:
extension [A, B](fa: F[A, B])
/** Аккумулирование всех `A` и `B`. */
def bifoldMap[M](f: A => M)(g: B => M)(using ma: Monoid[M]): M
/** Аккумулирование до `C`, начиная "справа". */
def bifoldRight[C](z: => C)(f: (A, C) => C)(g: (B, C) => C): C =
fa.bifoldMap[C => C](f.curried)(g.curried)(using endoMonoid[C])(z)
/** Аккумулирование до `C`, начиная "слева". */
def bifoldLeft[C](z: C)(f: (C, A) => C)(g: (C, B) => C): C =
fa.bifoldMap[C => C](a => c => f(c, a))(b => c => g(c, b))(using dual(endoMonoid[C]))(z)
/** Выделение Foldable из первого параметра. */
def leftFoldable[R]: Foldable[[X] =>> F[X, R]] =
new Foldable[[X] =>> F[X, R]]:
extension [A](fa: F[A, R])
override def foldMap[B](f: A => B)(using mb: Monoid[B]): B =
fa.bifoldMap[B](f)(_ => mb.empty)
/** Выделение Foldable из второго параметра. */
def rightFoldable[L]: Foldable[[X] =>> F[L, X]] =
new Foldable[[X] =>> F[L, X]]:
extension [A](fa: F[L, A])
override def foldMap[B](f: A => B)(using mb: Monoid[B]): B =
fa.bifoldMap[B](_ => mb.empty)(f)
/** Унифицирование Foldable на обоих параметрах. */
def uFoldable: Foldable[[X] =>> F[X, X]] =
new Foldable[[X] =>> F[X, X]]:
extension [A](fa: F[A, A])
override def foldMap[B](f: A => B)(using mb: Monoid[B]): B =
fa.bifoldMap[B](f)(f)
Примеры
Either
given eitherBifoldable: Bifoldable[Either] with
extension [A, B](fa: Either[A, B])
def bifoldMap[M](f: A => M)(g: B => M)(using ma: Monoid[M]): M =
fa match
case Right(value) => g(value)
case Left(value) => f(value)
Ссылки: