英文:
Parse error, possiby identation or mismatch brackets
问题
我正在用Haskell编写一个程序,但是我无法摆脱一个错误:
mountTree :: [Char] -> FilePath -> Int -> Either IO [FilePath] String
mountTree promatiList toScan 0 = do
b <- getDirectoryContests(initial)
return mountTree getDirectoryContests initial 1
mountTree [] [] 0 = do
print "没有要删除的内容"
mountTree primariList toScan dir = do
primariList <- getDirectoryContests(primariList)
where
if length(primariList) == dir then
return "完成"
else
toScan[leaf] = []
if dir > 0 then
toScan ++ mapM_ (++) mountTree(initialDir, toScan(leaf), dir + 1)
else
let value = if length(toScan) == 0
then
pop primariList
map (primariList, toScan(leaf), 0)
else
if length(toScan[leaf]) == initialDir then
leaf + 1
mountTree(initialDir, toScan(tmpLeaf), (dir + 1))
else
mountTree(primariList, toScan(dir + 1), (dir + 1))
main :: IO ()
main done = print done
main = do
initialPath <- getLine
tree = mountTree(intitialPath)
mapM_ (\x -> x) tree
哪里出错了,我该如何解决这个错误?
我已经搜索过了,但没有找到错误,包括管道操作符的使用。忘掉算法,专注于解析错误。
英文:
I'm writing a program in haskell but I doesn't get rid of an error:
mountTree :: [Char] -> FilePath -> Int -> Either IO [FilePath] String
mountTree promatiList toScan 0 = do
b <- getDirectoryContests(initial)
return mountTree getDirectoryContests initial 1
mountTree [] [] 0 = do
print "Nothing to delete"
mountTree primariList toScan dir = do
primariList <- getDirectoryContests(primariList)
where
if length(primariList) == dir then
return "Done"
else
toScan[leaf] = []
if dir > 0 then
toScan ++ mapM_ (++) mountTree(initialDir, toScan(leaf), dir + 1)
else
let value = if length(toScan) == 0
then
pop primariList
map (primariList, toScan(leaf), 0)
else
if length(toScan[leaf]) == initialDir then
leaf + 1
mountTree(initialDir, toScan(tmpLeaf), (dir + 1))
else
mountTree(primariList, toScan(dir + 1), (dir + 1))
main :: IO ()
main done = print done
main = do
initialPath <- getLine
tree = mountTree(intitialPath)
mapM_ (\x -> x) tree
Where are the error an how I can get rid of it error?
I've search but not found an error, including the use of pipe operator. FOrget the algorithn and focus on the parse error.
答案1
得分: 0
以下是您要翻译的内容:
解析错误是以下行的结果:
let value = if length(toScan) == 0
由于它出现的位置,编译器期望一个 let ... in ...
表达式,因此当 main
定义出现在第一列时,它会提前结束缩进块并扫描 in
关键字。
通常,这种类型的错误是缩进错误或多余的括号导致的,这就是为什么错误消息会这样说的原因。
修复此解析错误的一种方法是删除文本 "let value = "
。这将修复这个特定的解析错误,但您将会得到其他错误:一个关于在模式中使用 if...then...else
语法的错误,另一个关于在函数应用中出现意外的 if
表达式的错误。
也有可能修复这些错误,以便至少可以完全解析(并开始抱怨未定义的变量)。我已经附上了修复后的代码。
然而,评论中已经有两位人分享了他们的观点,认为这段代码无法工作,我也同意他们的观点。对于某些编程语言,您可以编写一些充满错误的草稿代码,让编译器/解释器的错误消息“引导”您编写工作的代码,对于这些语言,这种方法可能是学习语言的好方法。
出于各种原因,这对于 Haskell 来说效果不佳。当您写下以下内容时:
leaf + 1
mountTree(initialDir, toScan(tmpLeaf), (dir + 1))
编译器“理解”了这一点,但是当您认为自己正在将 leaf
增加并调用具有三个参数的 mountTree
时,编译器认为您正在将 leaf
添加到应用于两个参数 mountTree
和一个三元组的函数 1
中。在寻找将 1
转换为两个参数函数的方法时,您可能会收到一个关于非常奇怪的函数类型缺少 Num
实例的编译器错误消息。编译器无法为您提供有用的错误消息,因为您和编译器对于这段代码应该表示什么意思存在较大分歧。
您的程序有许多类似的错误,几乎每一行都包含了代码,这些代码“有效”,但与您的意图完全不同。您会发现将这个程序转化为可工作代码的过程会令人沮丧和泄气。
最好以更自下而上的方式学习 Haskell,从一些不真正“执行”任何操作的非常简单的“程序”开始。与其尝试编写一个在文件系统上执行递归操作的完整程序,您可能应该编写一个从列表中提取前 n
个元素的函数,这是非常基础教程中会找到的程序类型。我建议您通过查看 https://stackoverflow.com/q/1012573/7203016 中提到的一些初学者材料来开始学习。请注意,这个问题有一个非常高票的答案,但其他答案中也有一些很好的提示,所以也要看看那些答案。
无论如何,以下是我成功解析的程序版本,尽管如上所述,从这里将其转化为实际工作的代码可能会非常困难:
mountTree promatiList toScan 0 = do
b <- getDirectoryContents(initial)
return mountTree getDirectoryContents initial 1
mountTree [] [] 0 = do
print "Nothing to delete"
mountTree primariList toScan dir = do
primariList <- getDirectoryContents(primariList)
if length(primariList) == dir then
return "Done"
else do
let toScan[leaf] = []
if dir > 0 then
toScan ++ mapM_ (++) mountTree(initialDir, toScan(leaf), dir + 1)
else
if length(toScan) == 0
then
pop primariList
map (primariList, toScan(leaf), 0)
else
if length(toScan[leaf]) == initialDir then
leaf + 1
mountTree(initialDir, toScan(tmpLeaf), (dir + 1))
else
mountTree(primariList, toScan(dir + 1), (dir + 1))
main :: IO ()
main done = print done
main = do
initialPath <- getLine
let tree = mountTree(intitialPath)
mapM_ (\x -> x) tree
希望这可以帮助您理解代码。如果您需要更多的帮助,请随时提问。
英文:
The parse error is the result of the line:
let value = if length(toScan) == 0
Because of where this appears, the compiler is expecting a let ... in ...
expression, so it is scanning for the in
keyword when the main
definition appears in the first column and prematurely ends the indented block.
Often, this kind of error is the result of an indentation mistake or an extra parenthesis, which is why the error message says what it does.
One way to fix this parse error is to delete the text "let value = "
. That will fix this particular parse error, but you will get additional errors: one about using if...then...else
syntax in a pattern, and another about an unexpected if
expression in a function application.
It's possible to fix these errors, too, to get a version that will at least parse completely (and start complaining about undefined variables). I've attached it below.
However, two people in the comments have already shared their opinion that this code cannot be made to work, and I have to agree with them. With some programming languages, you can write some draft code that's full of errors and let the compiler/interpreter error messages "guide" you to working code, and for those languages, this approach might be a good way to learn the language.
For a variety of reasons, this doesn't work well for Haskell. When you write:
leaf + 1
mountTree(initialDir, toScan(tmpLeaf), (dir + 1))
the compiler "understands this", but while you think you're incrementing leaf
and then calling mountTree
with three arguments, the compiler thinks you're adding leaf
to the function 1
applied to two arguments, mountTree
and a three-element tuple. As it searches for a way to turn 1
into a two-argument function, you're likely to get a compiler error message about a missing Num
instance for a really weird function type. The compiler can't provide you with a useful error message because you and the compiler are too far from agreeing on what this code should mean.
Your program has many similar errors, with nearly every line containing code that's "valid" but means something completely different from what you intended. You will find the process of trying to turn this program into working code a frustrating and demoralizing experience.
It's probably better to learn Haskell with a more bottom-up approach, starting with really simple "programs" that don't really do anything. Instead of trying to write a full program to perform a recursive operation on a filesystem, you should maybe be writing a function to extract the first n
elements from a list, the sort of programs you find in very basic tutorials. I'd suggest working through some of the beginner materials mentioned in the answers to https://stackoverflow.com/q/1012573/7203016. Note that this question has one, extremely highly voted answer, but there are good tips in some of the other answers, too, so look through those as well.
Anyway, here's the version of the program that I got to parse okay, though -- as I said above -- I think getting it from here to actually working code will be very difficult:
mountTree promatiList toScan 0 = do
b <- getDirectoryContests(initial)
return mountTree getDirectoryContests initial 1
mountTree [] [] 0 = do
print "Nothing to delete"
mountTree primariList toScan dir = do
primariList <- getDirectoryContests(primariList)
if length(primariList) == dir then
return "Done"
else do
let toScan[leaf] = []
if dir > 0 then
toScan ++ mapM_ (++) mountTree(initialDir, toScan(leaf), dir + 1)
else
if length(toScan) == 0
then
pop primariList
map (primariList, toScan(leaf), 0)
else
if length(toScan[leaf]) == initialDir then
leaf + 1
mountTree(initialDir, toScan(tmpLeaf), (dir + 1))
else
mountTree(primariList, toScan(dir + 1), (dir + 1))
main :: IO ()
main done = print done
main = do
initialPath <- getLine
let tree = mountTree(intitialPath)
mapM_ (\x -> x) tree
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论