Scala Language
monaden
Zoeken…
Monade definitie
Informeel is een monade een container met elementen, genoteerd als F[_] , vol met 2 functies: flatMap (om deze container te transformeren) en unit (om deze container te maken).
Veelvoorkomende bibliotheekvoorbeelden zijn List[T] , Set[T] en Option[T] .
Formele definitie
Monad M is een parametrisch type M[T] met twee bewerkingen flatMap en unit , zoals:
trait M[T] {
def flatMap[U](f: T => M[U]): M[U]
}
def unit[T](x: T): M[T]
Deze functies moeten voldoen aan drie wetten:
- Associativiteit :
(m flatMap f) flatMap g = m flatMap (x => f(x) flatMap g)
Dat wil zeggen, als de volgorde ongewijzigd is, kunt u de voorwaarden in willekeurige volgorde toepassen. Dus het toepassen vanmopfen vervolgens het toepassen van het resultaat opglevert hetzelfde resultaat op als het toepassen vanfopgen vervolgens het toepassen vanmop dat resultaat. - Linker eenheid :
unit(x) flatMap f == f(x)
Dat wil zeggen dat de eenheids-monade vanxkaart gebracht overfgelijk is aan het toepassen vanfopx. - Rechter eenheid :
m flatMap unit == m
Dit is een 'identiteit': elke monade die in kaart wordt gebracht tegen de eenheid zal een monade retourneren die gelijkwaardig is aan zichzelf.
Voorbeeld :
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
- Associativiteit :
(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)
- Linker eenheid
unit(x).flatMap(x => f(x)) == f(x)
List(1).flatMap(x => x * x) == 1 * 1
- Juiste eenheid
//m flatMap unit == m
m.flatMap(unit) == m
List(1, 2, 3).flatMap(x => List(x)) == List(1,2,3) //Boolean = true
Standaard collecties zijn monaden
De meeste standaardcollecties zijn monaden ( List[T] , Option[T] ) of monade-achtig ( Either[T] , Future[T] ). Deze collecties kunnen eenvoudig worden gecombineerd binnen for begrip (wat een gelijkwaardige manier is om flatMap transformaties te schrijven):
val a = List(1, 2, 3)
val b = List(3, 4, 5)
for {
i <- a
j <- b
} yield(i * j)
Het bovenstaande komt overeen met:
a flatMap {
i => b map {
j => i * j
}
}
Omdat een monade de datastructuur bewaart en alleen op de elementen binnen die structuur inwerkt, kunnen we eindeloze monadische datastructuren ketenen, zoals hier voor een begrip wordt getoond.