将“Just []”变为“Nothing”

时间:2013-03-13 10:41:47

标签: haskell monads

以下一行

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

输出

Just [2,1]

和行

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

显示

Just []

但我希望输出 Nothing 。可以采取哪些措施来引入一些适用于所有使用列表的monad函数的更改?那么我应该使用别的东西而不是filterM,或者我可以从Maybe monad做一些继承吗?

3 个答案:

答案 0 :(得分:11)

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

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

答案 1 :(得分:8)

定义:

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

然后

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

答案 2 :(得分:6)

对于使用列表的所有monad函数,我不确定你的意思。无法修改列表monad,因此任何monad函数都会自动执行此操作,因为这需要有效地更改其他一些未知monad的绑定。同样,更改所有monad函数会耗费一些时间。

我的建议是使用可组合性。如果内部monad列表失败,我们想要的是在外部monad m中失败。这应该相当容易,虽然我不确定该怎么称呼它,所以我将使用failing

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

然后failing $ filterM (\x -> Just (x > 0)) []应该做你想做的事。

我不确定为什么你在这种情况下完全涉及Maybe(因为你的过滤条件都只使用Just),但我假设你有其他理由这样做,或者其他一些条件,有时会失败。