[英]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.