Using the Maybe Monad in “reverse”

末鹿安然 提交于 2019-12-04 14:59:44

问题


Let's say I have a number of functions:

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

And I want to compose them in the following way: If f returns Nothing, compute g. If g returns Nothing, compute h. If any of them compute Just a, stop the chain. And the whole composition (h . g . f) should of course return Maybe a.

This is the reverse of the typical use of the Maybe monad, where typically you stop computing if Nothing is returned.

What's the Haskell idiom for chaining computations like this?


回答1:


mplus is exactly what you're looking for, part of the MonadPlus typeclass. Here's its definition:

instance MonadPlus Maybe where
   mzero = Nothing

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

To use it in your case:

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



回答2:


mplus is probably better, but this should work as well:

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

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



回答3:


I guess you mean:

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

Using MonadPlus

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

You might want to use the StateT Monad:

function = runReaderT $ ReaderT f `mplus` ReaderT g `mplus` ReaderT h

f,g,h are ReaderT a Maybe b (up to the ReaderT)

or using msum:

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


来源:https://stackoverflow.com/questions/5606228/using-the-maybe-monad-in-reverse

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!