Buscar..


Definición de la mónada

Informalmente, una mónada es un contenedor de elementos, anotados como F[_] , empaquetados con 2 funciones: flatMap (para transformar este contenedor) y unit (para crear este contenedor).

Los ejemplos de bibliotecas comunes incluyen List[T] , Set[T] y Option[T] .

Definicion formal

La mónada M es un tipo paramétrico M[T] con dos operaciones flatMap y unit , como:

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

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

Estas funciones deben cumplir tres leyes:

  1. Asociatividad : (m flatMap f) flatMap g = m flatMap (x => f(x) flatMap g)
    Es decir, si la secuencia no se modifica, puede aplicar los términos en cualquier orden. Por lo tanto, aplicar m a f , y luego aplicar el resultado a g dará el mismo resultado que aplicar f a g , y luego aplicar m a ese resultado.
  2. Unidad izquierda : unit(x) flatMap f == f(x)
    Es decir, la unidad de la mónada de x asignada de forma plana a través de f es equivalente a aplicar f a x .
  3. Unidad derecha : m flatMap unit == m
    Esta es una "identidad": cualquier mónada con plano mapeado contra unidad devolverá una mónada equivalente a sí misma.

Ejemplo :

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. Asociatividad
(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. Unidad izquierda
unit(x).flatMap(x => f(x)) == f(x)
List(1).flatMap(x => x * x) == 1 * 1

  1. Unidad derecha
//m flatMap unit == m
m.flatMap(unit) == m
List(1, 2, 3).flatMap(x => List(x)) == List(1,2,3) //Boolean = true

Las colecciones estándar son mónadas

La mayoría de las colecciones estándar son mónadas ( List[T] , Option[T] ), o similares a mónadas ( Either[T] , Future[T] ). Estas colecciones se pueden combinar fácilmente dentro for comprensiones (que son una forma equivalente de escribir transformaciones de flatMap ):

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

Lo anterior es equivalente a:

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

Debido a que una mónada conserva la estructura de datos y solo actúa sobre los elementos dentro de esa estructura, podemos construir estructuras de datos monádicas en cadena sin fin, como se muestra aquí en una para comprensión.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow