2011-04-09 22 views
38

Digamos que tengo una serie de funciones:Uso de la Mónada Tal vez en "marcha atrás"

f :: a -> Maybe a 
g :: a -> Maybe a 
h :: a -> Maybe a 

Y quiero componerlos de la siguiente manera: Si la rentabilidad f Nada, calcular g. Si g no devuelve nada, calcule h. Si alguno de ellos calcula Solo a, detenga la cadena. Y toda la composición (h.g.f.) debería regresar, por supuesto. Tal vez a.

Esto es el reverso del uso típico de la mónada Maybe, donde normalmente se detiene la computación si no se devuelve nada.

¿Cuál es el modismo de Haskell para encadenar cálculos como este?

Respuesta

42

mplus es exactamente lo que está buscando, que forma parte de la clase de tipos MonadPlus. Aquí es su definición:

instance MonadPlus Maybe where 
    mzero = Nothing 

    Nothing `mplus` ys = ys 
    xs  `mplus` _ys = xs 

utilizarlo en su caso:

combined x = (f x) `mplus` (g x) `mplus` (h x) 
+10

Alternativa (el análogo de funtores aplicativos) estaría bien también como '(<|>)' es lo mismo que 'mplus' para Maybe. –

+1

O podría usar Data.Generics.Aliases.orElse – Landei

3

supongo que quiere decir:

f,g,h:: a -> Maybe b 

Usando MonadPlus

f x `mplus` g x `mplus` h x 

Es posible que desee utilizar el Statet Mónada:

f, g, h son ReaderT un Maybe b (hasta el ReaderT)

o mediante MSUM:

function = runReaderT $ msum $ map ReaderT [f,g,h] 
4

mplus es probablemente mejor, pero esto debería funcionar así:

import Data.List 
import Data.Maybe 
import Control.Monad 

join $ find isJust [f x, g y, h z] 
Cuestiones relacionadas