¿Qué mónada es lo opuesto al error mónada en Haskell?

9

En la mónada de error, la primera falla detiene cualquier ejecución aún más, simplemente llevando la falla a través de los siguientes enlaces.

¿Qué mónada se detiene en el éxito solo llevando éxitos y básicamente tragándose cualquier falla e intentando el siguiente enlace sin tener en cuenta el fracaso del anterior?

La mónada de error podría usarse para tratar este fracaso como un éxito, pero tengo curiosidad por saber si las bibliotecas predeterminadas tienen una mónada para este propósito específico, casi como una mónada O en mi mente "Haz esto o aquello"

Editar:

El comportamiento sería:

Left "fail" >>= (\x -> Right "win") >>= (\x -> Left "ahh neener") >>= (\x -> Right (x + " yay"))

En la mónada de error, el primer valor izquierdo solo se transfiere, por lo que el resultado es Left "fail". El comportamiento que quiero es donde lo anterior devuelve Right "win yay", es una mónada trivial para implementar que podría escribir yo mismo, pero pensé que algo existía para hacer eso (tal vez no usar Either, pero eso es lo primero que se me ocurre para ese comportamiento).

Jimmy Hoffa
fuente
¿Por qué el voto negativo? ¿Hay algo malo en esta pregunta?
Jimmy Hoffa
¿Podría proporcionar un pequeño fragmento de código para mostrar lo que piensa?
Daniel Gratzer
¿Podría ser que estás pensando en retroceder?
scarfridge

Respuestas:

4

Lo que necesita es MonadPlus (consulte también la wiki de Haskell ). Se define

mzero :: m a

que representa un error no especificado, y

mplus :: m a -> m a -> m a

que intenta el segundo cálculo, si el primero falla. También se proporcionan algunas funciones auxiliares:

-- Extends `mplus` to lists of computations:
msum :: MonadPlus m => [m a] -> m a
-- Fails a computation conditionally.
guard :: MonadPlus m => Bool -> m ()
-- Filter (fail) computations that don't satisfy the predicate.
mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a

Las instancias de MonadPlusse pueden dividir en dos categorías:

  1. mpluscombina todos los resultados posibles de sus dos argumentos (satisface la ley de Distribución Izquierda). []y Seqson probablemente los únicos casos con este comportamiento.
  2. mplusselecciona el argumento izquierdo, si contiene un valor válido, de lo contrario, selecciona el derecho (satisface la ley Left Catch). Instancias con este comportamiento son Maybe, Either, STMy IO.

( MonadPlusinstancia de Eithersolía definirse en Control.Monad.Error como

instance (Error e) => MonadPlus (Either e) where
    mzero            = Left noMsg
    Left _ `mplus` n = n
    m      `mplus` _ = m

pero por alguna razón parece faltar en la versión actual).

Consulte también MonadPlus en Wikilibros y la definición de MonadPlus para Haskell IO .

Petr Pudlák
fuente
Gracias, parece que la lista de monadplus es el pensamiento que tuve.
Jimmy Hoffa
@JimmyHoffa Olvidé mencionar que Seqtambién es una instancia de MonadPlus. Lo recomiendo encarecidamente [], porque la concatenación ( mplus) para Seqes O (log n) mientras que la concatenación de listas es O (n) .
Petr Pudlák
El wiki de Haskell es muy esclarecedor, parece que la comunidad de Haskell está pensando en qué dirección debería ir de la misma manera que yo estoy pensando en qué dirección quiero que funcione; si quiero que sea un O como un "Esto o aquello" o un entonces, "Esto entonces eso" donde el primer fallo provoca un comportamiento como O usar el valor anterior al fallo para el siguiente, pero un éxito todavía llama al el siguiente a diferencia de Or y utiliza el valor devuelto por la primera función.
Jimmy Hoffa
Sí, apoyo la propuesta de reforma de MonadPlus , creo que esto aclararía mucho las cosas.
Petr Pudlák