Sök…


Monad Definition

Informellt är en monad en behållare med element, noterade som F[_] , packade med två funktioner: flatMap (för att transformera denna behållare) och unit (för att skapa denna behållare).

Vanliga biblioteksexempel inkluderar List[T] , Set[T] och Option[T] .

Formell definition

Monad M är en parametrisk typ M[T] med två operationer flatMap och unit , såsom:

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

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

Dessa funktioner måste uppfylla tre lagar:

  1. Associativitet : (m flatMap f) flatMap g = m flatMap (x => f(x) flatMap g)
    Det vill säga, om sekvensen är oförändrad kan du tillämpa villkoren i vilken ordning som helst. Således applicerar m till f , och sedan applicerar resultatet på g ger samma resultat som applicerar f till g , och sedan applicerar m på det resultatet.
  2. Vänster enhet : unit(x) flatMap f == f(x)
    Det vill säga, enhetsmonaden för x platt-mappad över f motsvarar tillämpningen av f till x .
  3. Höger enhet : m flatMap unit == m
    Detta är en 'identitet': varje monad som är platt-mappad mot enhet kommer att returnera en monad motsvarande sig själv.

Exempel :

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. Associativitet :
(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. Vänster enhet
unit(x).flatMap(x => f(x)) == f(x)
List(1).flatMap(x => x * x) == 1 * 1

  1. Höger enhet
//m flatMap unit == m
m.flatMap(unit) == m
List(1, 2, 3).flatMap(x => List(x)) == List(1,2,3) //Boolean = true

Standardsamlingar är monader

De flesta av standardsamlingarna är monader ( List[T] , Option[T] ) eller monadliknande ( Either[T] , Future[T] ). Dessa samlingar kan enkelt kombineras inom for förstå (som är ett likvärdigt sätt att skriva flatMap transformationer):

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

Ovanstående motsvarar:

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

Eftersom en monad bevarar datastrukturen och endast agerar på elementen i den strukturen, kan vi oändliga monadiska datastrukturer, som visas här i en förståelse.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow