我有以下简化代码(实际代码确实实现了一些有意义的东西):
import Data.Char
import Data.Maybe
import Control.Monad
import Control.Applicative
testA :: [Int] -> Maybe Int -> Maybe Int
testA [] _ = Nothing
testA _ Nothing = Nothing
testA (x:xs) v = case x of
1 -> (+) <$> v <*> return x
otherwise -> testA xs v
testB :: (MonadPlus m, Applicative m) => [Int] -> m Int -> m Int
testB [] _ = mzero
testB _ mzero = mzero
testB (x:xs) v = case x of
1 -> (+) <$> v <*> return x
otherwise -> testB xs v
main = do
let xpto = testA [1,2,3,1,5] (Just 5)
print xpto
let ypto = testB [1,2,3,1,5] (Just 5)
print ypto
我的理解是 testA 和 testB 在使用 Maybe Monad 时应该表现相同,这意味着 mzero 应该转换为 Nothing。
然而,在测试 B ghc 实际上给出了一个警告:
Pattern match(es) are overlapped
In an equation for `testB': testB (x : xs) v = ..
并且输出不同:
Just 6 (correct)
Just 5 (incorrect)
我不确定我可能会丢失什么,为什么 mzero 不等于模式匹配中的任何内容?