Recherche…


Monad Définition

De manière informelle, une monade est un conteneur d'éléments, notés F[_] , contenant 2 fonctions: flatMap (pour transformer ce conteneur) et unit (pour créer ce conteneur).

Les exemples courants de bibliothèque incluent List[T] , Set[T] et Option[T] .

Définition formelle

Monad M est un type paramétrique M[T] avec deux opérations flatMap et unit , telles que:

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

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

Ces fonctions doivent satisfaire à trois lois:

  1. Associativité : (m flatMap f) flatMap g = m flatMap (x => f(x) flatMap g)
    En d'autres termes, si la séquence reste inchangée, vous pouvez appliquer les termes dans n'importe quel ordre. Ainsi, appliquer m à f , puis appliquer le résultat à g donnera le même résultat que si l'on appliquait f à g , puis appliquer m à ce résultat.
  2. Unité de gauche : unit(x) flatMap f == f(x)
    C'est-à-dire que la monade d'unité de x cartographiée à travers f équivaut à appliquer f à x .
  3. Unité droite : m flatMap unit == m
    C'est une «identité»: toute monade à plat contre une unité retournera une monade équivalente à elle-même.

Exemple :

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é de gauche
unit(x).flatMap(x => f(x)) == f(x)
List(1).flatMap(x => x * x) == 1 * 1

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

Les collections standard sont des monades

La plupart des collections standard sont des monades ( List[T] , Option[T] ) ou des monades (E Either[T] , Future[T] ). Ces collections peuvent être facilement combinées entre elles for compréhensions (qui sont une manière équivalente d'écrire des transformations flatMap ):

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

Ce qui précède est équivalent à:

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

Étant donné qu'une monade préserve la structure de données et n'agit que sur les éléments de cette structure, nous pouvons sans fin mettre en place des structures de données monadiques, comme illustré ici pour une compréhension.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow