gpt4 book ai didi

haskell - 如何在 Haskell 中正确使用一元表达式而不会出现解析错误?

转载 作者:行者123 更新时间:2023-12-03 14:40:07 24 4
gpt4 key购买 nike

我在 Windows 7 上运行 GHC 7.8.3 版。

好的,这与花哨的代码片段无关。我只是想在这里不要成为菜鸟,并且实际上以一种与副作用语言的结构类似的方式来编译一些东西。

我有以下代码:

main = 
do {
let x = [0..10];
print x
}

I've learned here ,关键字 do 是花哨的单子(monad)表达式的花哨的语法糖。当我尝试编译它时,我收到以下错误:
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 ,该 print 是花哨的等价物的语法糖:
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 中正确使用单子(monad)表达式而不会出现解析错误?有希望吗?

最佳答案

我花了一段时间才看到这里实际发生了什么:

main = 
do {
let x = [0..10];
print x
}

上面看起来好像我们有一个 do有两个陈述,这很好。当然,当缩进隐式插入它们时,使用显式大括号和分号并不常见。但他们不应该受到伤害......为什么上面的解析失败?

真正的问题是 let打开一个新区 block ! let block 没有大括号,所以缩进规则适用。该 block 以定义 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

关于haskell - 如何在 Haskell 中正确使用一元表达式而不会出现解析错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30695451/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com