Haskell newbie indentation query.

Hello All~ I have just started with Haskell, and I must confess; I am in love with it. However one area that I am really confused about is indentation. Lets take a look at if-else if- else block. The way I understand it: {------} if something then do something 1 something2 else if nothing then do something3 something4 else do different {-------} The code above gives out an error. I have been programming in python and the above appears fine. But it does not work. What works is: if something then do something1 something2 else if then do something3 something4 else do different I find the above scheme extremely confusing. I tried going to: http://en.wikibooks.org/wiki/Programming:Haskell_indentation after reading I am even more confused. Can somebody please explain how the Haskell indentation works? The else-if and else seem to be aligning up with "then". They should be aligning with "If" in my opinion. Thanks in advance. Regards -Vivek Ramaswamy-

Am Mittwoch, 15. Oktober 2008 13:39 schrieb Ramaswamy, Vivek:
Hello All~
I have just started with Haskell, and I must confess; I am in love with it. However one area that I am really confused about is indentation. Lets take a look at if-else if- else block.
The way I understand it: {------} if something then do something 1 something2 else if nothing then do something3 something4 else do different {-------} The code above gives out an error. I have been programming in python and the above appears fine. But it does not work. What works is: if something then do something1 something2 else if then do something3 something4 else do different
I find the above scheme extremely confusing. I tried going to:
Not for long, it'll become natural pretty fast.
http://en.wikibooks.org/wiki/Programming:Haskell_indentation after reading I am even more confused. Can somebody please explain how the Haskell indentation works?
The else-if and else seem to be aligning up with "then". They should be aligning with "If" in my opinion.
The "then ..." and the "else ..." branches are both part of the if-expression, so they have to be indented further than the "if". Aligning something with the "if" ends the expression, so if the "else" is aligned with the "if", there's an incomplete if-expression and something which should be an expression but isn't because it begins with "else". The Layout rule is explained in the report: http://haskell.org/onlinereport/ informally in section 2.7, formally in section 9.3, perhaps that helps.
Thanks in advance.
Regards -Vivek Ramaswamy-

Ramaswamy, Vivek wrote:
Hello All~
I have just started with Haskell, and I must confess; I am in love with it.
However one area that I am really confused about is indentation.
Lets take a look at if-else if- else block.
Important point 1. There are two contexts in haskell programs. Layout and non-layout. In a non-layout context you can do whatever you like with indentation. You can put the newlines wherever you want. In practice, almost everyone uses layout for the 'top-level' of a module. That means that anything flush to the left margin starts a new declaration. However, making sure we are not flush to the left margin, the following are all fine x = if True then 1 else 2 x = if True then 1 else 2 x = if True then 1 else 2 x = if True then 1 else 2 because, layout is not relevant in expressions. Now, "do blocks" are layout blocks. So what you really want us to look at is the use of if/then/else in do blocks. x = do if True then (return 1) else (return 2) The first line in the do block defines the left margin for this block. In this example, the first line is the "if" line, that defines the left margin. Since the "then" and the "else" are also both on the left margin, they are new statements. So, the layout interprets as: do {if True; then (return 1); else (return 2)} ...which is a parse error, because a statement cannot begin with 'then' or 'else'. any pattern of indentation which keeps the if expression indented further to the right will be OK, such as x = do if True then (return 1) else (return 2) x = do if True then (return 1) else (return 2) ..are both fine. Does that help? Jules

Simon Michael wrote:
Does that help?
It helps me a lot. I never clearly understood that there are these two different layout modes in my code (coddled by haskell-mode!) This will cut down some more guesswork. Thanks!
There is a new indentation module which does much better at the indentation stuff: http://kuribas.hcoop.net/haskell-indentation.el Jules

On Wed, Oct 15, 2008 at 5:25 PM, Jules Bean
There is a new indentation module which does much better at the indentation stuff:
I didn't realize until I tried to use yours that there are two indentation modules in haskell-mode, and I'd been using the inferior one. This does mean I can't tell what changes you have made, though. If it's not too much trouble, could you summarize your changes? Also, is this code going to make it into haskell-mode proper, or are there issues preventing that? If the latter, I wouldn't mind having a darcs repository to pull from.

Svein Ove Aas wrote:
On Wed, Oct 15, 2008 at 5:25 PM, Jules Bean
wrote: There is a new indentation module which does much better at the indentation stuff:
I didn't realize until I tried to use yours that there are two indentation modules in haskell-mode, and I'd been using the inferior one.
This one isn't mine. It was written by the IRC nick 'kuribas'. His real name is in the elisp.
This does mean I can't tell what changes you have made, though. If it's not too much trouble, could you summarize your changes?
Basically it has a more accurate haskell parser, and it has a simpler way of cycling through possible indentations: TAB moves to the right and BACKSPACE to the left.
Also, is this code going to make it into haskell-mode proper, or are there issues preventing that? If the latter, I wouldn't mind having a darcs repository to pull from.
Good question. I don't know. I don't know if haskell-mode is actively maintained. Jules

Basically it has a more accurate haskell parser, and it has a simpler way of cycling through possible indentations: TAB moves to the right and BACKSPACE to the left.
Unfortunately, it can sometimes fail to parse what's in the buffer, get balky and event prevent you typing anything at all. I had to back out of it for now..

On Thu, Oct 16, 2008 at 12:57:05PM -0700, Simon Michael wrote:
Basically it has a more accurate haskell parser, and it has a simpler way of cycling through possible indentations: TAB moves to the right and BACKSPACE to the left.
Unfortunately, it can sometimes fail to parse what's in the buffer, get balky and event prevent you typing anything at all. I had to back out of it for now..
You can use C-q followed by any character to insert a literal copy of that character, disregarding modes in effect (C-q C-j for a newline). I have to use this every so often to get around the kind of parse errors you mention, but I think it's still well worth the improved tab/backspace behavior. (In my experience these parsing bugs only affect editing on the same line or maybe the next line.) Regards, Reids

Thanks Jules and Daniel. That was very helpful. Regards -Vivek Ramaswamy- -----Original Message----- From: Jules Bean [mailto:jules@jellybean.co.uk] Sent: 15 October 2008 18:19 To: Ramaswamy, Vivek Cc: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] Haskell newbie indentation query. Ramaswamy, Vivek wrote:
Hello All~
I have just started with Haskell, and I must confess; I am in love with it.
However one area that I am really confused about is indentation.
Lets take a look at if-else if- else block.
Important point 1. There are two contexts in haskell programs. Layout and non-layout. In a non-layout context you can do whatever you like with indentation. You can put the newlines wherever you want. In practice, almost everyone uses layout for the 'top-level' of a module. That means that anything flush to the left margin starts a new declaration. However, making sure we are not flush to the left margin, the following are all fine x = if True then 1 else 2 x = if True then 1 else 2 x = if True then 1 else 2 x = if True then 1 else 2 because, layout is not relevant in expressions. Now, "do blocks" are layout blocks. So what you really want us to look at is the use of if/then/else in do blocks. x = do if True then (return 1) else (return 2) The first line in the do block defines the left margin for this block. In this example, the first line is the "if" line, that defines the left margin. Since the "then" and the "else" are also both on the left margin, they are new statements. So, the layout interprets as: do {if True; then (return 1); else (return 2)} ...which is a parse error, because a statement cannot begin with 'then' or 'else'. any pattern of indentation which keeps the if expression indented further to the right will be OK, such as x = do if True then (return 1) else (return 2) x = do if True then (return 1) else (return 2) ..are both fine. Does that help? Jules

Hello Vivek, Wednesday, October 15, 2008, 3:39:54 PM, you wrote: i think that practical answer is suggestion to use `case` instead: case () of _ | x < 5 -> do abc def ... | x==5 -> do ... | otherwise -> do ... it's pretty common pattern for haskell -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
participants (7)
-
Bulat Ziganshin
-
Daniel Fischer
-
Jules Bean
-
Ramaswamy, Vivek
-
Reid Barton
-
Simon Michael
-
Svein Ove Aas