在“反向”中使用Maybe Monad

时间:2011-04-09 16:26:08

标签: haskell monads

假设我有很多功能:

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

我想用以下方式组合它们:如果f返回Nothing,则计算g。如果g返回Nothing,则计算h。如果其中任何一个计算Just a,请停止链。而整个构图(例如f)当然应该返回Maybe a。

这与Maybe monad的典型用法相反,如果没有返回,通常会停止计算。

像这样链接计算的Haskell成语是什么?

3 个答案:

答案 0 :(得分:44)

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) 

答案 1 :(得分:4)

mplus可能更好,但这也应该有效:

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

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

答案 2 :(得分: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 Maybe b(直到ReaderT)

或使用msum:

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