一个涉及putStrLn的谜

时间:2019-02-20 21:36:20

标签: haskell syntax-error io-monad do-notation

为什么下面的代码段会产生错误parse error on input ‘putStrLn’

main = do line <- fmap reverse getLine
   putStrLn $ "You said " ++ line ++ " backwards!"
   putStrLn $ "Yes, you said " ++ line ++ " backwards!"

<interactive>:11:4: error: parse error on input ‘putStrLn’

此外,为什么以下代码段会产生错误parse error on input ‘let’

main = do line <- getLine
  let line' = reverse line
  putStrLn $ "You said " ++ line' ++ " backwards!"
  putStrLn $ "Yes, you said " ++ line' ++ " backwards!"


 <interactive>:31:4: error: parse error on input ‘let’

2 个答案:

答案 0 :(得分:13)

两个片段都有相同的问题。如果将do块的第一个动作与do本身放在同一行,则仍必须缩进do块中的其余动作,直到第一个动作为止一。修复它的两种选择:

main = do line <- fmap reverse getLine
          putStrLn $ "You said " ++ line ++ " backwards!"
          putStrLn $ "Yes, you said " ++ line ++ " backwards!"

main = do
   line <- fmap reverse getLine
   putStrLn $ "You said " ++ line ++ " backwards!"
   putStrLn $ "Yes, you said " ++ line ++ " backwards!"

答案 1 :(得分:3)

当在整个过程中使用显式分隔符时,它也适用:

main = do { line <- fmap reverse getLine ;
   putStrLn $ "You said " ++ line ++ " backwards!" ;
   putStrLn $ "Yes, you said " ++ line ++ " backwards!" }

main = do { line <- getLine ;
   let { line' = reverse line } ;                     -- NB let's { }s
   putStrLn $ "You said " ++ line' ++ " backwards!" ;
   putStrLn $ "Yes, you said " ++ line' ++ " backwards!" }

这不是好的缩进样式的替代品,而是对它的补充。