12

我正在尝试在 ghci 中以交互方式创建一个 do 块。只要我不使用 in 块定义变量,就可以了:

Prelude>let a = do putStrLn "test"; putStrLn "other test"
Prelude>

但我无法弄清楚如何在 do 块中交互地定义 let 构造而不会出现解析错误:

Prelude> let a = do let b = 5; putStrLn $ show b

<interactive>:2:40:
    parse error (possibly incorrect indentation or mismatched brackets)

明显地

let a = do
     let b = 5
     putStrLn $ show b

在 Haskell 源文件中完全没问题。我只是无法弄清楚如何将其转换为 ghci。

4

4 回答 4

15

试试这个:

let a = do let { b = 5 } ; print b 

let块可以包含多个声明,因此您必须在它们完成时告诉 GHCi - 这就是该行中括号的含义。

顺便说一句,您可以使用printfor putStrLn . show

于 2013-03-07T14:12:12.650 回答
13
:help

 <statement>                 evaluate/run <statement>    
:{\n ..lines.. \n:}\n        multiline command

您可以键入:{启动多行命令,然后键入:}结束它。

所以就这样做

 Prelude> :{
 Prelude| let a = do
 Prelude|     let b=5
 Prelude|     putStrLn $ show b
 Prelude| 
 Prelude| :} 

小心布局(缩进/空白)。否则,您可能会在明显正确的代码中出现解析错误。

例如,以下将不起作用,因为缩进不够深:

Prelude> :{
Prelude| let a = do
Prelude|    let b=5
Prelude|    putStrLn $ show b
Prelude| 
Prelude| :}

它会导致这样的解析错误:

<interactive>:50:4: parse error on input ‘let’
于 2013-03-07T14:21:15.670 回答
1

我原以为放入大括号会很好,但这并不能解析:

ghci> let a = do {let b = 5; putStrLn (show b)}

您始终可以采用多行方法,该方法确实有效:

ghci> :{
ghci| let a = do let b = 5
ghci|            putStrLn $ show b
ghci| :} 
于 2013-03-07T14:07:00.220 回答
1

我来到这里是因为我有同样的问题,但是 yatima2975 的回答让我想起了每个 let-block 可以有多个绑定,所以我尝试了下面的方法,确实有效。

$ ghci
GHCi, version 8.8.3: https://www.haskell.org/ghc/  :? for help
Prelude> do { let { x = 1; y = 2 }; putStrLn (show (x, y)) }
(1,2)
于 2020-05-05T14:04:26.393 回答