Search code examples
haskellghchlint

Parse error, possiby identation or mismatch brackets


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.


Solution

  • 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 Getting started with Haskell. 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