Suche…


Monade-Definition

Informell handelt es sich bei einer Monade um einen Container mit Elementen, der als F[_] , und enthält zwei Funktionen: flatMap (um diesen Container zu transformieren) und unit (um diesen Container zu erstellen).

Übliche Bibliotheksbeispiele sind List[T] , Set[T] und Option[T] .

Formale Definition

Monade M ist ein parametrischer Typ M[T] mit zwei Operationen flatMap und unit , wie:

trait M[T] {
  def flatMap[U](f: T => M[U]): M[U]
}

def unit[T](x: T): M[T]

Diese Funktionen müssen drei Gesetze erfüllen:

  1. Assoziativität : (m flatMap f) flatMap g = m flatMap (x => f(x) flatMap g)
    Das heißt, wenn die Reihenfolge unverändert ist, können Sie die Bedingungen in beliebiger Reihenfolge anwenden. Wenn Sie also m auf f anwenden und dann das Ergebnis auf g anwenden, erhalten Sie dasselbe Ergebnis wie das Anwenden von f auf g und das anschließende Anwenden von m auf dieses Ergebnis.
  2. Linke Einheit : unit(x) flatMap f == f(x)
    Das heißt, die Einheitsmonade von x flach über f abgebildet ist, entspricht der Anwendung von f auf x .
  3. Rechte Einheit : m flatMap unit == m
    Dies ist eine 'Identität': Jede gegen Einheit gemappte Monade gibt eine Monade zurück, die ihrer selbst entspricht.

Beispiel :

val m = List(1, 2, 3)
def unit(x: Int): List[Int] = List(x)
def f(x: Int): List[Int] = List(x * x)
def g(x: Int): List[Int] = List(x * x * x)
val x = 1
  1. Assoziativität :
(m flatMap f).flatMap(g) == m.flatMap(x => f(x) flatMap g) //Boolean = true
//Left side:
List(1, 4, 9).flatMap(g) // List(1, 64, 729)
//Right side:
 m.flatMap(x => (x * x) * (x * x) * (x * x)) //List(1, 64, 729)

  1. Linke Einheit
unit(x).flatMap(x => f(x)) == f(x)
List(1).flatMap(x => x * x) == 1 * 1

  1. Rechte Einheit
//m flatMap unit == m
m.flatMap(unit) == m
List(1, 2, 3).flatMap(x => List(x)) == List(1,2,3) //Boolean = true

Standardsammlungen sind Monaden

Die meisten Standardsammlungen sind Monaden ( List[T] , Option[T] ) oder monadenähnlich ( Either[T] , Future[T] ). Diese Sammlungen können leicht miteinander kombiniert werden , in for Comprehensions (welche eine äquivalente Art des Schreibens flatMap Transformations):

val a = List(1, 2, 3)
val b = List(3, 4, 5)
for {
  i <- a
  j <- b
} yield(i * j)

Das obige ist äquivalent zu:

a flatMap {
  i => b map {
    j => i * j
  }
}

Da eine Monade die Datenstruktur bewahrt und nur auf die Elemente innerhalb dieser Struktur einwirkt, können wir endlose monadische Datenstrukturen verketten, wie hier zum Verständnis gezeigt.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow