Haskell do块中如何允许表达式

Haskell do块中如何允许表达式,haskell,Haskell,在下面的代码第4行中,我在do块的两个IO操作之间夹了一个表达式: 1 doubleX :: (Show x, Num x) => x -> IO ()

在下面的代码第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行粘在一起。

我将从我非常相似的答案中抄袭出来(尽管可能不是重复的,因为这个问题没有明确地涉及

给出了从do语法到内核Haskell的完整翻译;与你的问题相关的部分是:

因此,您的代码如下所示:

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))

它被粘成一个
let。。在
statement中,但是如果它被“去糖化”,那会是什么样子呢?
putStrLn(“我现在将加倍”+(show x))>>让double=x*2在putStrLn中(“结果是”+(show double))
好吧,现在我觉得自己很笨。我认为let是一个独立的表达式,可以用1+2之类的东西代替。这更有意义。谢谢
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))