2011-04-09 72 views
38

比方说,我有很多的功能:“反向”

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

而且我想他们撰写以下列方式:若f返回任何计算克如果g返回Nothing,则计算h。如果他们中的任何一个计算Just a,则停止链。而整个作品(例如f)当然应该返回Maybe a。

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

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

回答

42

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) 
+10

替代(模拟的应用型函子)也可以,因为'(<|>)'与Maybe的'mplus'相同。 – 2011-04-09 19:51:47

+1

或者你可以使用Data.Generics.Aliases.orElse – Landei 2011-04-09 22:12:58

3

我猜你的意思是:

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

使用MonadPlus

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

您可能需要使用StateT单子:

F,G,H是ReaderT一个也许b(达到ReaderT)

或使用MSUM:

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

mplus可能是更好的,但这应该工作以及:

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

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