MonadPlus
Формальное определение
Класс типов MonadPlus
предназначен для монад,
которые также могут действовать как моноиды.
MonadPlus
должен удовлетворять законам монад и моноидов.
Определение в виде кода на Scala
trait MonadPlus[F[_]] extends Monad[F], ApplicativePlus[F]:
def filter[A](fa: F[A])(f: A => Boolean): F[A] =
fa.flatMap(a => if f(a) then unit(a) else empty[A])
def unite[T[_], A](value: F[T[A]])(using T: Foldable[T]): F[A] =
value.flatMap(ta => T.foldMap(ta)(a => unit(a))(using monoid[A]))
MonadPlus
позволяет определить операцию filter
, позволяющую фильтровать по предикату элементы монады.
А также операцию unite
, позволяющую "схлопывать" F[T[A]]
при наличии Foldable[T]
.
Например, список List(Some(785727510), Some(0), Some(1), None, None, Some(1))
"схлопывается" до
List(785727510, 0, 1, 1)
.
Примеры
Связанный список
given MonadPlus[List] with
override def unit[A](a: => A): List[A] = List(a)
override def apply[A, B](fab: List[A => B])(fa: List[A]): List[B] =
fab.flatMap { aToB => fa.map(aToB) }
override def plus[A](fa1: List[A], fa2: => List[A]): List[A] = fa1 ++ fa2
override def empty[A]: List[A] = List.empty[A]
extension [A](fa: List[A]) override def flatMap[B](f: A => List[B]): List[B] = fa.flatMap(f)
Реализация
Реализация в ScalaZ
import scalaz.*
import Scalaz.*
// ... Все операции родителей
List(1, 2, 3) filter {_ > 2} // List(3)
(1 |-> 50) filter { x => x.shows contains '7' } // [7,17,27,37,47]
Ссылки: