簡體   English   中英

是否已在GHC 8.6.5中刪除了在do塊中使用let語句的能力?

[英]Has the ability to use let statements in do blocks been removed in GHC 8.6.5?

我在ghci輸入了一些代碼,類似於:

main = do { a <- getLine ; let b = "Hello " ++ a ; putStrLn b }

但是,我收到此錯誤:

<interactive>:1:63: error: parse error on input `}'

在以前版本的Haskell / GHC中,我記得這很好用 - 它甚至明確地說,在do塊中,你不需要in關鍵字。 然而,讓這個工作的唯一方法似乎是:

main = do { a <- getLine ; let b = "Hello " ++ a in putStrLn b }

這不會產生這個錯誤。

這被刪除了嗎? 如果是這樣,我是否需要在let in表達式中使用第二個do塊?

let是一個類似do的布局關鍵字,既可以作為do塊中的語句,也可以作為let ... in ...表達式,因為它引入了一個綁定 這個:

main = do
  a <- getLine
  let b = "Hello " ++ a
  putStrLn b

Desugars to this:

main = do {
  a <- getLine;
  let {
    b = "Hello " ++ a;
  };
  putStrLn b;
};

雖然你寫的東西等同於:

main = do {
  a <- getLine;
  let {
    b = "Hello " ++ a;
    putStrLn b
  };
};

所以GHC自然會期待一些其他的東西 - 一個模式或者= -after putStrLn b ,因為你可以用一個名為b的參數定義一個名為putStrLn的本地函數。 解決方案是在let語句中使用顯式括號:

main = do { a <- getLine; let { b = "Hello " ++ a }; putStrLn b }

或者在GHCi中使用多行模式,使用:{ command,以:}命令終止:

> :{
| main = do
|   a <- getLine
|   let b = "Hello " ++ a
|   putStrLn b
| :}
>

或者使用:set +m ,並以空行結束:

> :set +m
| main = do
|   a <- getLine
|   let b = "Hello " ++ a
|   putStrLn b
|
>

其次是:unset +m返回單行模式。

問題在於它將你的putStrLn b解析為let聲明,因此它基本上將它解析為:

do { a <- getLine; let { b = "Hello " ++ a ; putStrLn b } }

因此,它在putStrLn部分中尋找a = ,您將在其中定義putStrLn函數。 因此,解析器具有“想法”,即您正在定義函數,而不是調用函數。

實際上,我們可以寫例如:

Prelude> let a = 3; f b = b + 1
Prelude> f a
4

所以這里我們在同一行中聲明了兩個變量。

您可以使用大括號來明確let的范圍僅為b ,例如:

do { a <- getLine; let { b = "Hello " ++ a }; putStrLn b }

let的優先級是由於語法,在第3章: Haskell'10報告中的 表達式定義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM