According to the Haskell indentation rules, "Code which is part of some expression should be indented further in than the beginning of that expression". However, I found the following example, which seems to violate the rule above, compiles without any error or warning:
someFunction :: Bool -> Int -> Int -> Int
someFunction condition a b = if condition
then a - b
else a + b
Here I am defining a function someFunction
, its body is an if-then-else
block. According to the indentation rule, the then
block is a part of the same expression in the first line, so it should be indented further than its previous line. Yet in my example, the second line then
starts at the same column as the first line, and this example compiles.
I am not sure what is going on here. I am working with GHC version 8.0.1.
Haskell relies on indentation to reduce the verbosity of your code. Despite some complexity in practice, there are really only a couple fundamental layout rules.
No, Haskell indentation is not like Python. Haskell is not about indentation levels, it's all about making things line up with other things.
Here is the general syntax of using the if-else conditional statement in Haskell. if<Condition> then <True-Value>else <False-Value> In the above expression, Condition − It is the binary condition which will be tested. True-Value − It refers to the output that comes when the Condition satisfies
Haskell without if-then-else syntax makes Haskell more logical and consistent. There is no longer confusion to beginners like: "What is so special about if-then-else, that it needs a separate syntax? I though it could be simply replaced by a function. Maybe there is some subtlety that I'm not able to see right now."
False-Value − It refers to the output that comes when the condition does not satisfy. As Haskell codes are interpreted as mathematical expressions, the above statement will throw an error without else block. The following code shows how you can use the if-else statement in Haskell −
Haskell is not intended to be a minimalistic language, but to be one that is easy to read. if-then-else resembles a phrase from English language. It shows clearly which expression is returned on a fulfilled condition, and which one is returned for an unsatisfied condition. It is thus easier to read.
I'm reasonably sure this is an artifact of a deliberate GHC variation on the indentation rule. Nice catch!
GHC reads this
foo = do
item
if a
then b
else c
item
as
foo = do {
item ;
if a ;
then b ;
else c ;
item }
which should trigger a parse error.
However, this was so common that at a certain point the GHC devs decided to allow for an optional ;
before then
and else
. This change to the if
grammar makes the code compile.
This means that if
became "special", in that it does not have to indented more, but only as much as the previous item. In the code posted in the question, then
is indented as much as the previous item, so there's an implicit ;
before it, and that makes the code compile.
I would still try to avoid this "style", though, since it's quirky.
(Personally, I wouldn't have added this special case to GHC. But it's not a big deal, anyway.)
I now noticed that the Wikibook mentions this variant as a "proposal" for a future version of Haskell. This is a bit outdated now, and has been implemented in GHC since then.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With