Haskell - 调用失败的构造如何从 Monad 运行?
Haskell - How the construct do calls fail function from Monad?
在研究 Monads 时,我理解了为什么当 列表定义 上的模式匹配失败时,它的计算有点 "ignored" 而不是抛出错误:
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
应用程序使用 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)
然而,正如预期的那样,在这种情况下,相对于 List
的单子函数 fail
将不会被调用,就像在之前的情况中那样:
*Main> test''
[(1,1),(1,2)*** Exception: test.hs:11:40-82: Non-exhaustive patterns in lambda
所以,我的问题是:是否有可能使用 test''
样式以简洁的方式获得 [(1,1),(1,2),(3,1),(3,2)]
? do
是否为这样的东西构造了语法糖?
test'' :: [(Int, Int)]
test'' = [Just 1, Nothing, Just 3] >>= \maybeX -> [1, 2] >>= \y -> case maybeX of Just x -> return (x, y)
_ -> fail undefined
*Main> test''
[(1,1),(1,2),(3,1),(3,2)]
*Main> test'' == test
True
比如
{-# LANGUAGE LambdaCase #-}
test'' = [Just 1, Nothing, Just 3] >>= \case
Just x -> [1, 2] >>= \y -> return (x, y)
_ -> fail "..."
在研究 Monads 时,我理解了为什么当 列表定义 上的模式匹配失败时,它的计算有点 "ignored" 而不是抛出错误:
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
应用程序使用 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)
然而,正如预期的那样,在这种情况下,相对于 List
的单子函数 fail
将不会被调用,就像在之前的情况中那样:
*Main> test''
[(1,1),(1,2)*** Exception: test.hs:11:40-82: Non-exhaustive patterns in lambda
所以,我的问题是:是否有可能使用 test''
样式以简洁的方式获得 [(1,1),(1,2),(3,1),(3,2)]
? do
是否为这样的东西构造了语法糖?
test'' :: [(Int, Int)]
test'' = [Just 1, Nothing, Just 3] >>= \maybeX -> [1, 2] >>= \y -> case maybeX of Just x -> return (x, y)
_ -> fail undefined
*Main> test''
[(1,1),(1,2),(3,1),(3,2)]
*Main> test'' == test
True
比如
{-# LANGUAGE LambdaCase #-}
test'' = [Just 1, Nothing, Just 3] >>= \case
Just x -> [1, 2] >>= \y -> return (x, y)
_ -> fail "..."