¿Qué hace exactamente a Option una mónada en Scala?


Sé lo que son las mónadas y cómo usarlas. Lo que no entiendo es lo que hace, digamos, Option una mónada?

En Haskell una mónada Maybe es una mónada porque está instanciada de la clase Monad (que tiene al menos 2 funciones necesarias return y bind que hace de la clase Monad, de hecho, una mónada).

Pero en Scala tenemos esto:

sealed abstract class Option[+A] extends Product with Serializable { ... }
trait Product extends Any with Equals { ... }

Nada relacionado con una mónada.

Si creo mi propia clase en Scala, ¿será una mónada por defecto? Por qué no?

Author: Erik Allik, 2014-08-18

3 answers

Monad es un concepto, una interfaz abstracta si se quiere, que simplemente define una forma de componer datos.

Option soporta composición a través de flatMap, y eso es casi todo lo que se necesita para usar la"insignia de la mónada".

Desde un punto de vista teórico, también debería:

  • admite una operación unit (return, en términos de Haskell) para crear una mónada a partir de un valor desnudo, que en el caso de Option es el constructor Some
  • respeta la monádica leyes

Pero esto no es estrictamente aplicado por Scala.

Las mónadas en scala son un concepto mucho más flexible que en Haskell, y el enfoque es más práctico. La única cosa para la que las mónadas son relevantes, desde la perspectiva del lenguaje, es la capacidad de ser utilizadas en un para-comprensión.

flatMap es un requisito básico, y usted puede opcionalmente proporcionar map, withFilter y foreach.

Sin embargo, no hay tal cosa como la conformidad estricta a un Monad tipo de clase, como en Haskell.

Aquí hay un ejemplo: definamos nuestra propia mónada.

class MyMonad[A](value: A) {
  def map[B](f: A => B) = new MyMonad(f(value))
  def flatMap[B](f: A => MyMonad[B]) = f(value)
  override def toString = value.toString
}

Como ves, solo estamos implementando map y flatMap (bueno, y toString como una mercancía). ¡Felicidades, tenemos una mónada! Vamos a probarlo:

scala> for {
  a <- new MyMonad(2)
  b <- new MyMonad(3)
} yield a + b
// res1: MyMonad[Int] = 5

Agradable! No estamos haciendo ningún filtrado, por lo que no necesitamos implementar withFilter. También dado que estamos produciendo un valor, no necesitamos foreach tampoco. Básicamente implementas todo lo que deseas apoyar, sin requisitos estrictos. Si intenta filtrar en un for-comprehension y no has implementado withFilter, simplemente obtendrás un error en tiempo de compilación.

 55
Author: Gabriele Petronella,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-18 18:25:27

Cualquier cosa que (parcialmente) implemente, a través deFilterMonadic el rasgo se considera una mónada en Scala. Esto es diferente de cómo se representan las mónadas en Haskell, o el Monad typeclass in scalaz . Sin embargo, para beneficiarse del azúcar sintáctico de comprensión for en Scala, un objeto tiene que exponer algunos de los métodos definidos en el rasgo FilterMonadic.

También, en Scala, el equivalente de la función Haskell return es la palabra clave yield utilizada para producir valores a partir de una comprensión for. El desugaring de yield es una llamada al método map de la "mónada".

 13
Author: Ionuț G. Stan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-18 11:35:19

La forma en que lo pondría es que hay una distinción emergente entre mónadas como un patrón de diseño vs.Una abstracción de primera clase. Haskell tiene esta última, en la forma de la clase de tipo Monad. Pero si tienes un tipo que tiene (o puede implementar) las operaciones monádicas y obedece las leyes, eso también es una mónada.

En estos días se puede ver mónadas como un patrón de diseño en las bibliotecas de Java 8. Los tipos Optional y Stream en Java 8 vienen con un método estático of que corresponde a Haskell return, y un método flatMap. Sin embargo, no existe un tipo Monad.

En algún punto intermedio también tienes el enfoque "tipo pato", como dice la respuesta de Ionuț G. Stan. C# también tiene esto: la sintaxis de LINQ no está vinculada a un tipo específico, sino que se puede usar con cualquier clase que implemente ciertos métodos.

 9
Author: Luis Casillas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-18 17:43:53