Haskell do 块中如何允许表达式
How are expressions allowed inside Haskell do blocks
在以下代码的第 4 行中,我在 do 块中的两个 IO 操作之间夹有一个表达式:
1 doubleX :: (Show x, Num x) => x -> IO ()
2 doubleX x = do
3 putStrLn ("I will now double " ++ (show x))
4 let double = x * 2
5 putStrLn ("The result is " ++ (show double))
我将 do 表示法理解为使用 >>= 或 >> 将单子操作链接在一起。但是当你在两者之间有一个表达式时,它是如何工作的呢?您不能使用 >>.
将第 3-5 行粘在一起
我将从我非常相似的答案中抄袭 here(尽管可能不是重复的,因为该问题没有明确处理 let
)。
Report 给出了从 do 语法到内核的完整翻译 Haskell;与您的问题相关的部分是:
do {e} = e
do {e;stmts} = e >> do {stmts}
do {let decls; stmts} = let decls in do {stmts}
所以你的代码像这样脱糖:
doubleX x = do
putStrLn ("I will now double " ++ (show x))
let double = x * 2
putStrLn ("The result is " ++ (show double))
==> do {e;stmts} rule
doubleX x =
putStrLn ("I will now double " ++ (show x)) >> do
let double = x * 2
putStrLn ("The result is " ++ (show double))
==> do {let decls; stmts} rule
doubleX x =
putStrLn ("I will now double " ++ (show x)) >>
let double = x * 2 in do
putStrLn ("The result is " ++ (show double))
==> do {e} rule
doubleX x =
putStrLn ("I will now double " ++ (show x)) >>
let double = x * 2 in
putStrLn ("The result is " ++ (show double))
在以下代码的第 4 行中,我在 do 块中的两个 IO 操作之间夹有一个表达式:
1 doubleX :: (Show x, Num x) => x -> IO ()
2 doubleX x = do
3 putStrLn ("I will now double " ++ (show x))
4 let double = x * 2
5 putStrLn ("The result is " ++ (show double))
我将 do 表示法理解为使用 >>= 或 >> 将单子操作链接在一起。但是当你在两者之间有一个表达式时,它是如何工作的呢?您不能使用 >>.
将第 3-5 行粘在一起我将从我非常相似的答案中抄袭 here(尽管可能不是重复的,因为该问题没有明确处理 let
)。
Report 给出了从 do 语法到内核的完整翻译 Haskell;与您的问题相关的部分是:
do {e} = e do {e;stmts} = e >> do {stmts} do {let decls; stmts} = let decls in do {stmts}
所以你的代码像这样脱糖:
doubleX x = do
putStrLn ("I will now double " ++ (show x))
let double = x * 2
putStrLn ("The result is " ++ (show double))
==> do {e;stmts} rule
doubleX x =
putStrLn ("I will now double " ++ (show x)) >> do
let double = x * 2
putStrLn ("The result is " ++ (show double))
==> do {let decls; stmts} rule
doubleX x =
putStrLn ("I will now double " ++ (show x)) >>
let double = x * 2 in do
putStrLn ("The result is " ++ (show double))
==> do {e} rule
doubleX x =
putStrLn ("I will now double " ++ (show x)) >>
let double = x * 2 in
putStrLn ("The result is " ++ (show double))