2
votes

I'm working on a large Haskell program, so I'm only including the code that seems relevant here to make the problem clearer. Please comment if I should include more.

When I compile, I get only one error message: "parse error (possibly incorrect indentation or mismatched brackets)"

Here is some code with no errors (printStmt) and a very similar section (VarDeclStmt) with the error directed at the line reading, "expr >>= \s ->". I don't see why one would be fine and the other would cause a problem. In what way are they different?

printStmt = 
            keyword "print" >>
            expr >>= \e ->
            symbol ";" >>
            return (Print e)

varDeclStmt = do
              keyword "var" >>
              expr >>= \s -> --ERROR
              symbol "=" >>
              expr >>= \e ->
              return (VarDecl s e) 
2

2 Answers

4
votes

This is an indentation issue. The block

varDeclStmt = do
              keyword "var" >>
              expr >>= \s -> --ERROR
              symbol "=" >>
              expr >>= \e ->
              return (VarDecl s e) 

parses as

varDeclStmt = do
              { keyword "var" >>
              ; expr >>= \s -> --ERROR
              ; symbol "=" >>
              ; expr >>= \e ->
              ; return (VarDecl s e) 
              }

which is nonsense, since the first entry keyword "var" >> is not valid.

Note that indenting the whole block further (or less) does not change how it is parsed.

The easiest fix is to remove do completely, so that the text below that is not parsed as a block, hence it is not split into separate entries, but parsed as if it were on a single line.

Otherwise, you can switch to proper do notation

varDeclStmt = do
              keyword "var"
              s <- expr
              symbol "="
              e <- expr
              return (VarDecl s e) 

or (worst solution), make the do block a single-entry one, making the block indented more than the first line, as follos

varDeclStmt = do
              keyword "var" >>
                expr >>= \s ->
                symbol "=" >>
                expr >>= \e ->
                return (VarDecl s e) 

The above solution is silly, though, since the purpose of do is splitting the block into entries, and the indentation is made so that there is only one entry. So, we use two things to counteract each other.

2
votes

The indentation error has to do with the do block. Try indenting after the do. Something like:

varDeclStmt = do
                keyword "var" >>
                expr >>= \s -> 
                symbol "=" >>
                expr >>= \e ->
                return (VarDecl s e)

Let me know if that works.