haskell monads typeclass monoids

haskell - Monoide vs MonadPlus



monads typeclass (3)

Debo enfatizar la muy importante diferencia: a diferencia de Monoid, y a diferencia de lo que dicen las otras respuestas, MonadPlus no proporciona un tipo con una operación binaria asociada y la identidad. Haskell Report, el único documento que puede reclamar el estado de la Norma, no especifica las leyes de MonadPlus y, por lo tanto, no requiere que mplus sea asociativa o mzero sea su unidad izquierda o derecha. Quizás los autores todavía estaban debatiendo las leyes: hay muy buenas razones para que mplus no sea asociativo. Por ejemplo, si mplus es asociativo pero no conmutativo, el cálculo de búsqueda no determinista representado por MonadPlus no puede estar completo (es decir, existen soluciones que no podemos encontrar). Como es bastante raro que mplus sea conmutativo, MonadPlus no puede representar ningún procedimiento completo de búsqueda no determinista, si insistimos en la asociatividad. Ha habido una discusión detallada de este mismo tema de las leyes de MonadPlus en Carolina del Sur: debe ser siempre asociativo

Esta pregunta ya tiene una respuesta aquí:

Soy muy nuevo tanto en Monads como en Monoids y recientemente también aprendí sobre MonadPlus . Por lo que veo, MonadPlus y MonadPlus proporcionan un tipo con una operación binaria asociativa y una identidad. (Llamaría a esto un semigrupo en lenguaje matemático). Entonces, ¿cuál es la diferencia entre MonadPlus y MonadPlus ?


Si tenemos que sostiene MonadPlus m , dirías que m es una Monad , pero ma (el tipo resultante de aplicar a a la "función" m ) es un monoide.

Si definimos (similar a la definición de Data.Monoid , pero la utilizaremos más adelante)

class Semigroup a where (<>) :: a -> a -> a class Semigroup a => Monoid a where zero :: a

entonces tiene

mzero :: MonadPlus m => m a mplus :: MonadPlus m => m a -> m a -> m a

Con tipos bastante comparables y las leyes apropiadas.

-- left and right identity mplus a mzero == a mplus mzero a == a -- associativity (a `mplus` b) `mplus` c == a `mplus` (b `mplus` c)

Incluso podemos definir un Haskell Monoid si usamos -XFlexibleInstances

{-# LANGUAGE FlexibleInstances #-} instance MonadPlus m => Semigroup (m a) where (<>) = mplus instance MonadPlus m => Monoid (m a) where zero = mzero

aunque estos se superponen mal con las instancias en Data.Monoid , que probablemente es la razón por la que no es una instancia estándar.

Otro ejemplo de un monoide como este es la Alternative m => ma de Control.Applicative .


Un semigroup es una estructura equipada con una operación binaria asociativa. Un monoid es un semigrupo con un elemento de identidad para la operación binaria.

Mónadas y semigrupos

Cada mónada tiene que adherirse a las leyes de la mónada . Para nuestro caso, lo importante es la ley de asociatividad. Expresado usando >>= :

(m >>= f) >>= g ≡ m >>= (/x -> f x >>= g)

Ahora apliquemos esta ley para deducir la asociatividad para >> :: ma -> mb -> mb :

(m >> n) >> p ≡ (m >>= /_ -> n) >>= /_ -> p ≡ m >>= (/x -> (/_ -> n) x >>= /_ -> p) ≡ m >>= (/x -> n >>= /_ -> p) ≡ m >>= (/x -> n >> p) ≡ m >> (n >> p)

(donde elegimos x para que no aparezca en m , n o p ).

Si nos especializamos >> en el tipo ma -> ma -> ma (sustituyendo b por a ), vemos que para cualquier tipo a la operación >> forma un semigrupo en ma . Como es cierto para cualquier a , obtenemos una clase de semigrupos indexados por a . Sin embargo, no son monoides en general, no tenemos un elemento de identidad para >> .

MonadPlus y monoides

MonadPlus agrega dos operaciones más, mplus y mzero . MonadPlus leyes de MonadPlus establecen explícitamente que mplus y mzero deben formar un monoide en ma para un arbitrario a . Entonces, nuevamente, obtenemos una clase de monoides indexados por a .

Note la diferencia entre MonadPlus y MonadPlus : Monoid dice que algún tipo único cumple con las reglas monoidales, mientras que MonadPlus dice que para todo lo posible, el tipo ma satisface las leyes monoidales. Esta es una condición mucho más fuerte.

Entonces, una instancia de MonadPlus forma dos estructuras algebraicas diferentes: una clase de semigrupos con >> y una clase de monoides con mplus y mzero . (Esto no es algo poco frecuente, por ejemplo, el conjunto de números naturales mayores que cero {1,2,...} forma un semigrupo con + y un monoide con × y 1 ).