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