haskell - learn - monad example
Usando la Mónada Maybe en "reverse" (3)
Digamos que tengo una serie de funciones:
f :: a -> Maybe a
g :: a -> Maybe a
h :: a -> Maybe a
Y quiero componerlos de la siguiente manera: si f no devuelve nada, calcule 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 dejas de computar si no se devuelve nada.
¿Cuál es el modismo de Haskell para encadenar cálculos como este?
Supongo que te refieres a:
f,g,h:: a -> Maybe b
Usando MonadPlus
f x `mplus` g x `mplus` h x
Es posible que desee utilizar StateT Monad:
function = runReaderT $ ReaderT f `mplus` ReaderT g `mplus` ReaderT h
f, g, h son ReaderT a Maybe b (hasta ReaderT)
o usando msum:
function = runReaderT $ msum $ map ReaderT [f,g,h]
mplus
es exactamente lo que estás buscando, parte de la MonadPlus
de MonadPlus
MonadPlus. Aquí está su definición:
instance MonadPlus Maybe where
mzero = Nothing
Nothing `mplus` ys = ys
xs `mplus` _ys = xs
Para usarlo en tu caso:
combined x = (f x) `mplus` (g x) `mplus` (h x)
mplus
es probablemente mejor, pero esto debería funcionar también:
import Data.List
import Data.Maybe
import Control.Monad
join $ find isJust [f x, g y, h z]