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

You can type :{ to start a multiline command, and type :} to end it.

So just do

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

Be careful with layout (indentation/whitespace). Otherwise you can get parse errors in apparently correct code.

For example the following will NOT work because the indentation isn't deep enough:

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

It will lead to a parse error like this:

<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 ブロックが複数のバインディングを持つ方法を思い出させたので、以下を試してみたところ、実際に機能しました。

$ 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 に答える