[Haskell-cafe] Is there a generic way to detect "mzero"?

Erik Hesselink hesselink at gmail.com
Mon Mar 26 21:58:13 CEST 2012


On Mon, Mar 26, 2012 at 21:24, Antoine Latter <aslatter at gmail.com> wrote:
> On Mon, Mar 26, 2012 at 1:33 PM, Ting Lei <tinlyx at hotmail.com> 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



More information about the Haskell-Cafe mailing list