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).
Respuestas:
Lo que necesita es MonadPlus (consulte también la wiki de Haskell ). Se define
que representa un error no especificado, y
que intenta el segundo cálculo, si el primero falla. También se proporcionan algunas funciones auxiliares:
Las instancias de
MonadPlus
se pueden dividir en dos categorías:mplus
combina todos los resultados posibles de sus dos argumentos (satisface la ley de Distribución Izquierda).[]
ySeq
son probablemente los únicos casos con este comportamiento.mplus
selecciona el argumento izquierdo, si contiene un valor válido, de lo contrario, selecciona el derecho (satisface la ley Left Catch). Instancias con este comportamiento sonMaybe
,Either
,STM
yIO
.(
MonadPlus
instancia deEither
solía definirse en Control.Monad.Error comopero 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 .
fuente
Seq
también es una instancia deMonadPlus
. Lo recomiendo encarecidamente[]
, porque la concatenación (mplus
) paraSeq
es O (log n) mientras que la concatenación de listas es O (n) .