以下一行
filterM (\x -> Just (x > 0)) [2, 1, 0, -1]
输出
Just [2,1]
和行
filterM (\x -> Just (x > 0)) []
显示
Just []
但我希望输出 Nothing 。可以采取哪些措施来引入一些适用于所有使用列表的monad函数的更改?那么我应该使用别的东西而不是filterM,或者我可以从Maybe monad做一些继承吗?
答案 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),但我假设你有其他理由这样做,或者其他一些条件,有时会失败。