1

I'm finding a very strange behavior for some Haskell code I'm working on. I'm working in a .hs file and the following simple function compiles in GHCi just fine:

func mat l =
    if mat == [1,0,0,0] then l
    else
        let trymat t = if t == 0 then trymat 1 else if t == 4 then error "Not ok!" else l
        in l

When I add a single newline, i.e.

func mat l =
    if mat == [1,0,0,0] then l
    else
        let trymat t =
            if t == 0 then trymat 1 else if t == 4 then error "Not ok!" else l
        in l

the compiler gets angry:

 λ> :load code.hs
    parse error (possibly incorrect indentation or mismatched brackets)
   |
67 |             if t == 0 then trymat 1 else if t == 4 then error "Not ok!" else l
   |             ^

This seems to happen no matter how I space out / parenthesize the inner if block, and also happens with cases. It's extra weird because trymat is a total dummy function: it's never even called again! Any clue why this is happening, and how I'll be able to add function definitions and cases and such in my code going forward? Thanks!

2
  • 1
    Unrelated to your question: you are defining a trymat function, but you are not using it. Commented May 2, 2020 at 7:43
  • @chi yes, I was attempting to trace exactly where the issue was by first getting rid of all calls to it and found that it was crashing even with just a definition. Commented May 2, 2020 at 22:30

1 Answer 1

5

Consider adding another variable in this let definition

func mat l =
    if mat == [1,0,0,0] then l
    else
        let trymat t =
            if t == 0 then trymat 1 else if t == 4 then error "Not ok!" else l
            anotherVar =
            "random value"
        in l

It is unclear from the indentation where there are variables and where the values are. Haskell requires you to add one more level of indentation to the values

func mat l =
    if mat == [1,0,0,0] then l
    else
        let trymat t =
                if t == 0 then trymat 1 else if t == 4 then error "Not ok!" else l
            anotherVar =
                "random value"
        in l

The general rule is that code which is part of some expression should be indented further in than the beginning of that expression. source

Sign up to request clarification or add additional context in comments.

2 Comments

I see; the second if needs that extra indent and it now compiles. Thanks!
@zjs: You can also reduce the need to align things like this by always inserting a newline+indent after layout keywords that introduce a block (e.g., do, let, of, where) when you expect their contents to span multiple lines. Alignment looks nice and improves readability in some circumstances, but avoiding it by default frees you from having to reindent things when you change function names or add parameters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.