upvote
> inner expressions must be indented more

Not to support the parent comment, which I disagree with, but If you use multi-line let-bindings, those require that you indent not just more than the previous line, but as much as the first token after the let keyword on the previous line. It’s a very strange rule, all the more surprising because it’s inconsistent even with the rest of the language. It is totally avoidable if you, like I think most experienced haskellers do, just prefer ‘where’, but people more familiar with procedural code usually lean into using ‘let’ everywhere because it feels more familiar.

I think the strange indentation used to be required in more places - I vaguely remember running into it a lot more when I started with Haskell 20 years ago, but that was also just when I was new to the language. These days I just keep ‘let’ to a bare minimum, so it doesn’t bother me. One thing that made Elm frustrating was that it disallowed ‘where’ clauses, forcing you to deal with this weird edge case all the time.

reply
So you want to line the equals signs up or similar?

  let
     f = 9
    fo = 10
   foo = 123
  in f+fo+foo
vs.

  let
    f = 9
    fo = 10
    foo = 123
  in f+fo+foo
reply
No, the issue is if the first binding is on the same line as the `let`, you are required to write, e.g.:

    someValue = let f = 9
                    fo = 10
                    foo = 123
      in f+fo+foo
rather than:

    someValue = let f = 9
      fo = 10
      foo = 123
      in f+fo+foo
I think it used to be the case that it had to be indented past the `=` or the `let` even if it was't on the same line. Note also that `in` has to be indented past `someValue`, but doesn't need to be indented as far `let`.

This is fine:

    someValue = let
      f = 9
      fo = 10
      foo = 123
      in f+fo+foo
So, it is possible to land on sane indentation, but the parser is much pickier than, e.g., Python's off-sides rule, so it takes some trial and error for new users to find it, and it can be frustrating if you're just temporarily modifying an expression to quickly try something out.

I honestly think it would be less surprising if the parser just disallowed writing the first binding on the same line as the `let` entirely, treating it only as a block, but some people (bewilderingly) do seem to prefer to write their code with the excessive indentation (I'd imagine with editor support, rather than manually maintaining the spacing).

reply
I feel like you are describing that the parser is too lenient rather than too picky. It could just require you to always put `let` and `in` on their own lines, in which case the indentation makes sense, I think. It's only when trying to keep more stuff on the same line that the details of Haskell's indentation rules come into play.
reply
> I couldn't disagree more

[proceeds to agree on all points]

Not even sure what to tell you... Have more introspection?

reply