简体   繁体   中英

Turn “Just []” into “Nothing”

The following line

filterM (\x -> Just (x > 0)) [2, 1, 0, -1] 

outputs

Just [2,1]

and the line

filterM (\x -> Just (x > 0)) [] 

shows

Just []

But I would like it to output Nothing . What can be done to possibly introduce some change that would work for all monad functions working with lists? So should I use something else instead of filterM or I can do some inheritance from Maybe monad?

您可以使用mfilter根据谓词将Just []转换为mfilter

 mfilter (not . null) . filterM (Just . (>0)) $ []

Define:

flatten :: Maybe [a] -> Maybe [a]
flatten Nothing   = Nothing
flatten (Just []) = Nothing
flatten x         = x

Then

flatten $ filterM (\x -> Just (x > 0)) []

I'm not sure what you mean in terms of working for all monad functions working with lists. There is no way to modify the list monad so that this will happen automatically with any monad function, as this would require effectively changing the bind of some other unknown monad. Likewise, changing all of the monad functions would be a bit time consuming.

My suggestion is to use composability. What we want is to fail in the outer monad m if the inner monad, list, is failing. This should be fairly easy, although I'm not sure what to call it, so I will use failing .

failing :: MonadPlus m => m [a] -> m [a]
failing = (=<<) $ \l -> case l of
    [] -> mzero
    _  -> return l

Then failing $ filterM (\\x -> Just (x > 0)) [] should do what you want.

I'm not sure why you're involving Maybe at all in this case though (as your filter conditions both only use Just), but I'm assuming you have some other reason for doing this, or some other condition that sometimes fails.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM