Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why parse error? Indentation?

I wrote this code:

addNums key num = add [] key num
    where add res a:as b:bs
        | a == [] = res
        | otherwise = add res:(a+b) as bs

At line 3 the interpreter says:

parse error (possibly incorrect indentation)

I could not find something wrong, neither with the code nor with the indentation. I put four spaces for each tab.

Annotation:

Even this does not compile:

addNums key num = add [] key num
    where add res a:as b:bs
            | a == [] = res
            | otherwise = add res:(a+b) as bs

Line 2:

Parse error in pattern: add

like image 231
user905686 Avatar asked Aug 24 '11 15:08

user905686


People also ask

What is parsing error in Python?

ParserError[source] Exception that is raised by an error encountered in parsing file contents. This is a generic error raised for errors encountered when functions like read_csv or read_html are parsing contents of a file.

What is parse error in Haskell?

The abstract data type ParseError represents parse errors. It provides the source position (SourcePos) of the error and a list of error messages ( A ParseError can be returned by the function parse. ParseError is an instance of the Show and Eq classes.

What does parsing error mean?

Here are some of the most common causes of the Android parse error: The app is not compatible with your device. Your phone does not have permission to install the app. The file you are trying to install is corrupt, incomplete, or damaged. Your antivirus or security app is preventing installation.

What does variable not in scope mean in Haskell?

(When GHC complains that a variable or function is "not in scope," it simply means that it has not yet seen a definition of it yet. As was mentioned before, GHC requires that variables and functions be defined before they are used.)


1 Answers

The main indendation rule in Haskell is that if you want to continue a definition on another line, it has to be further indented than the the thing you're defining. In this case the guards for your add function are less indented, so that's what the compiler is complaining about.

Disregarding the other errors in your code, the indentation should be something like this:

addNums key num = add [] key num
    where add res a:as b:bs
            | a == [] = res
            | otherwise = add res:(a+b) as bs

Also note that the exact amount of indentation does not matter, only the indentation of the continuing lines relative to the thing being defined.

Another syntactic problem with your code is that you seem to have misunderstood the precedence rules of Haskell. In Haskell, function application binds tighter than any operator, so add res a:as b:bs is parsed as (add res a):(as b):bs, while you meant add res (a:as) (b:bs).

The final problems are type errors. The (:) operator has the type a -> [a] -> [a], which means that it takes an element and a list, and produces a list. In your code res:(a+b), you appear to have this reversed, as res is a list and a+b is the element. Since there is no operator in Haskell to append a single element to the end of a list, you'll have to use the list concatenation operator (++) :: [a] -> [a] -> [a] instead: res ++ [a+b].

You're also comparing the element a to the list [] in your guard. This is probably not what you meant, and the pattern (a:as) would not match if the list was empty. The easiest solution to this is to add another pattern instead of your guard.

Putting all of this together, this code should hopefully do what you intended:

addNums key num = add [] key num
    where add res [] _ = res
          add res (a:as) (b:bs) = add (res ++ [a+b]) as bs

P.S. Repeatedly appending to the end of a list is not very efficient. In fact, it's O(n2). You might want to add to the front instead and reverse the list when you're done. This is O(n).


References:

  • Indentation
  • Pattern matching
like image 115
hammar Avatar answered Sep 28 '22 08:09

hammar