News for hackers. Stuff that matters.
Re:Reading Simple Haskell by culturedsystems on Saturday December 09, 2017 @10:06AM (#15886086)
One thing this doesn't mention, which might be useful to know, is that Haskell is indentation-sensitive. For instance, those examples using "let" won't compile if the lines beginning with "let" and "in" aren't indented.

I'd be interested if anyone knows of a simple guide to Haskell's indentation rules - I still find it trips me up now and then.

Re:Reading Simple Haskell by masklinn on Saturday December 09, 2017 @10:58AM (#15886326)
> Haskell is indentation-sensitive.

That's not really true, at least not in the way Python is. Haskell is actually defined using "braceful" syntax, and that syntax can be used anywhere (and is useful for code generation); on top of that it has Layout Rules[0].

Basically:

Any time a "where", "let", "do" or "of" keyword is not followed by a brace, an implicit one is inserted and the indentation of the next lexeme (non-comment non-whitespace item) is noted[1]

For any subsequent line,

* if it's indented by the same amount as the one noted, a semi-colon is prepended

* if it's indented by less than the noted amount, a closing brace is prepended

A closing brace is also inserted when encountering an illegal lexeme (for the current structure) where a a closing brace would be legal.

[0] https://www.haskell.org/onlinereport/haskell2010/haskellch2....

[1] except if the indentation of the next non-whitespace lexeme is less than the current indentation level, then an empty block is inserted, and layout processing for the current scope continues

Re:Reading Simple Haskell by seventydwarves on Saturday December 09, 2017 @08:34PM (#15889266)
Internally, Python is a lot like that, too - like in Haskell, the lexer adds in brace tokens when the code is indented an unindented, which keeps the grammar simpler. I guess the main difference here is that Haskell exposes the underlying whitespace-insensitive notation to the programmer, too, whereas Python keeps it hidden.
Re:Reading Simple Haskell by Tarean on Sunday December 10, 2017 @02:27PM (#15893026)
Haskell is also a LOT more lenient. So stuff like

    if x < 5
    then 42
    else x
       + 1
       + 2
is legal.
Re:Reading Simple Haskell by moomin on Saturday December 09, 2017 @12:49PM (#15886976)
I’d honestly appreciate some examples of non-indentation syntax. They’re think on the ground.
Re:Reading Simple Haskell by masklinn on Saturday December 09, 2017 @01:10PM (#15887074)
It's as noted above: put an opening brace after the "where", "let", "do" and "of" keywords[0], put semi-colons between (or after both work) "statements" in a given "scope" e.g. declarations (in let and where blocks), clauses (in case/of blocks) and actual statements (in do blocks)

    module Main where {
    main = do {
    let {
    a :: Int; a = 8;
    b :: Int; b = 3;
    };
    let { c = a `quot` b } in print c;
    }}
You can also format it all on one line, it'll work just fine:

    module Main where { main = do {let {a :: Int; a = 8; b :: Int; b = 3;}; let { c = a `quot` b }; print c}}
[0] basically every keyword which opens a non-expression "body", a brace after `case` or `in` is a compilation error as they can only contain a single expression
Re:Reading Simple Haskell by moomin on Saturday December 09, 2017 @03:09PM (#15887805)
Yeah, I think the real problem I have is the impossibility of opting out of the indentation style. Not using any indentation or newlines seems pretty extreme. All I want to do is write it like it was C, and that’s not possible (maybe we need yet another extension)
Re:Reading Simple Haskell by masklinn on Saturday December 09, 2017 @03:38PM (#15887977)
> Not using any indentation or newlines seems pretty extreme.

You can certainly use indentation and newlines, my examples were just demonstrating the ability to "obviously" not invoke layout since there's nowhere layout information can be.

Whether to use layout (braceless) or explicit structuring (braceful) is solely determined by a brace being present after a listed keyword, you can have any whitespace you want around it, and you can make that decision on a keyword-by-keyword basis[0] although it will apply to the entire block, so you can write

    module Main where -- no brace, layout rules

    main = do { -- brace, no layout
      let { a = 3 };
      let { b = 5 };
      print $ a + b;
    }
Now here the let statement (rather than expression) is a bit tricky because if we don't use the braces the ; will bind to the "let" which is not using layout, resulting in a parse error. An alternative — and the way do blocks normally desugar — is to use ; as a separator prefix, a style also used by e.g. Elm:

    module Main where

    main = do 
      { let a = 3
      ; let b = 5
      ; print $ a + b
      }
[0] this is very very useful when generating code which must surround user-provided code: the generated code can be braceful and the user-provided code can independently use layout without conflicts.
Re:Reading Simple Haskell by moomin on Saturday December 09, 2017 @05:00PM (#15888418)
Thank you. Need to spend a bit more time grokking this.
Re:Reading Simple Haskell by PaulAJ on Sunday December 10, 2017 @08:46AM (#15891342)
Also, comments are considered to be lexemes for this purpose.
Re:Reading Simple Haskell by tome on Saturday December 09, 2017 @10:16AM (#15886125)
> I'd be interested if anyone knows of a simple guide to Haskell's indentation rules - I still find it trips me up now and then.

The "simple" way I deal with it is to use Emacs and press TAB until things look right :)

Re:Reading Simple Haskell by Tehnix on Saturday December 09, 2017 @10:16AM (#15886127)
Re:Reading Simple Haskell by kkmx on Saturday December 09, 2017 @08:26PM (#15889236)
That helped thanks!