Scala Language
Monaden
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:
- 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 alsomauffanwenden und dann das Ergebnis aufganwenden, erhalten Sie dasselbe Ergebnis wie das Anwenden vonfaufgund das anschließende Anwenden vonmauf dieses Ergebnis. - Linke Einheit :
unit(x) flatMap f == f(x)
Das heißt, die Einheitsmonade vonxflach überfabgebildet ist, entspricht der Anwendung vonfaufx. - 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
- 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)
- Linke Einheit
unit(x).flatMap(x => f(x)) == f(x)
List(1).flatMap(x => x * x) == 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.