Ricerca…


Definizione di Monade

Informalmente, una monade è un contenitore di elementi, indicato come F[_] , ricco di 2 funzioni: flatMap (per trasformare questo contenitore) e unit (per creare questo contenitore).

Esempi di librerie comuni includono List[T] , Set[T] e Option[T] .

Definizione formale

Monad M è un tipo parametrico M[T] con due operazioni flatMap e unit , come ad esempio:

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

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

Queste funzioni devono soddisfare tre leggi:

  1. Associatività : (m flatMap f) flatMap g = m flatMap (x => f(x) flatMap g)
    Cioè, se la sequenza è invariata puoi applicare i termini in qualsiasi ordine. Quindi, applicando m f , e quindi applicando il risultato a g otterrà lo stesso risultato dell'applicazione di f a g applicando m a quel risultato.
  2. Unità sinistra : unit(x) flatMap f == f(x)
    Cioè, l'unità monad di x flat-mapped su f equivale a applicare f a x .
  3. Unità destra : m flatMap unit == m
    Questa è una "identità": qualsiasi unità monad flat-mapped restituirà una monade equivalente a se stessa.

Esempio :

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. Associatività :
(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. Unità sinistra
unit(x).flatMap(x => f(x)) == f(x)
List(1).flatMap(x => x * x) == 1 * 1

  1. Unità giusta
//m flatMap unit == m
m.flatMap(unit) == m
List(1, 2, 3).flatMap(x => List(x)) == List(1,2,3) //Boolean = true

Le collezioni standard sono Monade

La maggior parte delle raccolte standard sono monade ( List[T] , Option[T] ) o monad ( Either[T] , Future[T] ). Queste raccolte possono essere facilmente combinate insieme for comprensione (che è un modo equivalente di scrivere trasformazioni flatMap ):

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

Quanto sopra è equivalente a:

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

Poiché una monade conserva la struttura dei dati e agisce solo sugli elementi all'interno di quella struttura, possiamo disporre di infinite strutture monadiche a catena, come mostrato qui in una comprensione preliminare.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow