在研究Monads时,我理解为什么当列表定义上的模式匹配失败时,其计算会被忽略"忽略"而不是抛出错误:
test :: [(Int, Int)]
test = [(x, y) | (Just x) <- [Just 1, Nothing, Just 3], y <- [1, 2]]
*Main> test
[(1,1),(1,2),(3,1),(3,2)]
这是因为使用Monad
的{{1}}应用只是语法糖:
do
同样,我们可以尝试使用绑定运算符 test'' :: [(Int, Int)]
test'' = do
(Just x) <- [Just 1, Nothing, Just 3]
y <- [1, 2]
return (x, y)
*Main> test'
[(1,1),(1,2),(3,1),(3,2)]
*Main> test == test'
True
来模仿此逻辑:
>>=
但是,正如预期的那样,在这种情况下,不会像以前那样调用相对于test'' :: [(Int, Int)]
test'' = [Just 1, Nothing, Just 3] >>= \(Just x) -> [1, 2] >>= \y -> return (x, y)
的monadic函数fail
:
List
所以,我的问题是:是否有可能以一种整洁的方式使用*Main> test''
[(1,1),(1,2)*** Exception: test.hs:11:40-82: Non-exhaustive patterns in lambda
样式获得[(1,1),(1,2),(3,1),(3,2)]
? test''
是否为这样的事物构建了一个语法糖?
do
答案 0 :(得分:5)
例如
{-# LANGUAGE LambdaCase #-}
test'' = [Just 1, Nothing, Just 3] >>= \case
Just x -> [1, 2] >>= \y -> return (x, y)
_ -> fail "..."