
On Mon, Mar 26, 2012 at 21:24, Antoine Latter
On Mon, Mar 26, 2012 at 1:33 PM, Ting Lei
wrote: Hi,
I was writing a code trying to use MonadPlus to detect some error cases (representing missing values etc. in pure code). With the Maybe monad, I can do this:
can0 :: (a -> Maybe b) -> a -> Bool can0 f x = case f x of Nothing -> False Just x -> True
And I got the expected result:
*Main> can0 (\x -> Just x) 1 True
But, when I try to generalize this using MonadPlus, as follows:
can :: (MonadPlus m) => (a -> m b) -> a -> Bool can f x = case f x of mzero -> False _ -> True
I got a warning:
__testError.hs:31:11: Warning: Pattern match(es) are overlapped In a case alternative: _ -> ... Ok, modules loaded: Main.
Well, you can sort of do it with only MonadPlus - but it really depends on your choice of Monad whether or not it does anything like what you want:
can :: (MonadPlus m) => (a -> m ()) -> a -> m Bool can f x = (f x >> return True) <|> return false
For 'Maybe' this works great, but for something like 'List' I couldn't even tell you what it would do without reasoning through it.
So you might be better off with the suggestion from Tobias using Eq
Well, if you accept the following MonadPlus laws: mzero >>= f == mzero mzero `mplus` m == m Then you can say that for a well-behaving MonadPlus, mzero will return (only) False in that function. However, I don't think it's guaranteed that a non-mzero value will give (only) True. In fact, the list monad will always return the final False. Erik