我在Windows 7上运行GHC版本7.8.3。
好的,这不是关于花哨的代码片段。我只是想在这里不是一个菜鸟,并且实际上以一种模糊地类似于副作用语言结构的方式编译。
我有以下代码:
main =
do {
let x = [0..10];
print x
}
I've learned here,关键字do是花哨的monadic表达式的花哨的语法糖。当我尝试编译它时,我收到以下错误:
main.hs:4:1: parse error on input 'print'
我在this other question中学到了Haskell中的标签是邪恶的,所以我试图省略它们:
main =
do {
let x = [0..10];
print x
}
我失败了,因为解析错误仍然存在。
I've also learned here,该印刷品是花哨的等价物的语法糖:
main =
do {
let x = [0..10];
putStrLn $ show x
}
但后来我得到了这个错误:
main.hs:4:9: parse error on input 'putStrLn'
试图面对我的绝望,我试图省略let关键字after reading this answer:
main =
do {
x = [0..10];
print x
}
然后我得到:
main.hs:4:1: parse error on input '='
在最后的无用尝试中,我甚至试图省略';'像这样:
main =
do {
let x = [0..10]
print x
}
得到了:
main.hs:4:1: parse error on input 'print'
所以,
如何在Haskell中正确使用monadic表达式而不会出现解析错误?有什么希望吗?
答案 0 :(得分:15)
我花了一段时间才看到实际发生的事情:
main =
do {
let x = [0..10];
print x
}
以上看起来好像我们有一个带有两个语句的do
,这很好。当然,当缩进隐式插入它们时,使用显式括号和分号并不常见。但他们不应该受伤...为什么上面的解析失败?
真正的问题是let
打开了一个新区块! let
块没有大括号,因此缩进规则适用。该块以定义x = [0..10]
开头。然后找到一个分号,它承诺另一个定义如下。
let x = [0..10] ; y = ...
甚至
let x = [0..10] ;
y = ... -- must be indented as the x above, or more indented
然而,在分号后我们找到print
,它甚至缩进小于x
。根据缩进规则,这相当于插入括号:
main =
do {
let { x = [0..10]; }
print x
}
但上面没有解析。错误消息不是指隐式插入的大括号(这会非常令人困惑!),但仅限于下一行(不幸的是,在这种情况下几乎令人困惑)。
代码可以通过例如为let
提供明确的大括号:
main = do { let { x = [0..10] };
print x }
在上面,缩进完全不相关:您可以添加换行符和/或空格而不影响解析(例如在Java,C等中)。或者,我们可以移动下面的分号:
main = do { let x = [0..10]
; print x }
上面的分号位于下一行,并且缩进程度低于x
,隐式插入}
来关闭let
块。这里缩进很重要,因为let
使用缩进规则。如果我们更多地缩进分号,我们可能会导致我们之前发现的相同解析错误。
当然,最惯用的选择是对整个代码使用缩进规则:
main = do let x = [0..10]
print x
答案 1 :(得分:5)
我打算说,没有有用的信息,
main = do
let x = [0..10]
print x
正在为我工作,但我现在要阅读大括号内的in
。
稍微一点,我发现http://echo.rsmw.net/n00bfaq.html非常方便阅读有关身份/格式的内容。
答案 2 :(得分:4)
main = do let x = [0..10]
print x
适合我
等等
main = do { let x = [0..10]
in print x }
我认为您正在尝试混合使用不同的语法选项。