
Am Donnerstag, 9. März 2006 14:04 schrieb Martin Percossi:
Hello, the following code doesn't compile <snip> matMul :: MMatrix s -> MMatrix s -> ST s (MMatrix s) --matMul a b = do let foo = 2*5 --return a matMul a b = do { let foo = 2*5; return a } </snip>
under ghc 6.4.1, yielding the error message:
question.hs:25:41: parse error on input `<-' Failed, modules loaded: none. ?? my error message is what I expect: Matrix.hs:25:42: parse error on input `}' Failed, modules loaded: none.
There's no '<-' around.
The offending is line the one containing "let foo = 2*5", which is a little test I've done of let-clauses. Now, suppose instead that for the last function, matMul, I replace the version that's commented out. No errors!
Could someone enlighten me as to why? I'm a bit confused, as I thought the two forms are equivalent save for formatting...
The offending line is parsed as matMul a b = do { let { foo = 2*5; return a } } (cf. Sec. 9.3 of the report), which obviously doesn't make sense. This is because let expressions extend as far to the right as possible and separating local bindings by ';' is legitimate, so the parser tries to parse a binding for return after the semicolon, and fails. It isn't smart enough to then backtrack and let the let-binding end at the semicolon. This is one of the dangers of mixing explicit braces and layout. In the other version, layout leads to correct parsing, as will replacing the semicolon with an 'in' or changing the layout to matMul a b = do { let foo = 2*5 ; return a } I suggest using semicolons only as the first token on a line, aligned below the opening brace, then all's well.
This is on the back of a email discussion that I was reading about let-clauses, in which someone declared that they where better than where clauses for monadic code. If anyone could comment on this, I'd appreciate it as well.
Many thanks in advance, Martin
Cheers, Daniel -- "In My Egotistical Opinion, most people's C programs should be indented six feet downward and covered with dirt." -- Blair P. Houghton