Использование Maybe Monad в "reverse"
Скажем, у меня есть ряд функций:
f :: a -> Maybe a
g :: a -> Maybe a
h :: a -> Maybe a
И я хочу скомпоновать их следующим образом: Если f возвращает Nothing, вычислите g. Если g ничего не возвращает, вычислите h. Если какой-либо из них вычисляет Just a, остановите цепочку. И вся композиция (h. G. F) должна, конечно, вернуться. Возможно, a.
Это противоположность типичному использованию монады Maybe, где обычно вы перестаете вычислять, если ничего не возвращается.
Какая икома Haskell для целых вычислений вроде этого?
Ответы
Ответ 1
mplus
- это именно то, что вы ищете, часть класса MonadPlus
. Здесь его определение:
instance MonadPlus Maybe where
mzero = Nothing
Nothing `mplus` ys = ys
xs `mplus` _ys = xs
Чтобы использовать его в вашем случае:
combined x = (f x) `mplus` (g x) `mplus` (h x)
Ответ 2
mplus
, вероятно, лучше, но это тоже должно работать:
import Data.List
import Data.Maybe
import Control.Monad
join $ find isJust [f x, g y, h z]
Ответ 3
Я думаю, вы имеете в виду:
f,g,h:: a -> Maybe b
Использование MonadPlus
f x `mplus` g x `mplus` h x
Возможно, вы захотите использовать StateT Monad:
function = runReaderT $ ReaderT f `mplus` ReaderT g `mplus` ReaderT h
f, g, h - ReaderT a Возможно b (до ReaderT)
или используя msum:
function = runReaderT $ msum $ map ReaderT [f,g,h]