I just started learning Haskell and I briefly read through some of the indentation rules and it seems to me that Haskell behaves just like Python when it comes to indentation (I might be wrong). Anyway, I tried to write a tail recursive fibonacci function and I keep getting an indentation error and I don't know where I indented my code wrong.
ERROR message:
F1.hs:6:9: error:
parse error (possibly incorrect indentation or mismatched brackets)
|
6 | |n<=1 = b | ^
Code:
fib :: Integer -> Integer
fib n = fib_help n 0 1
where fib_help n a b
|n<=1 = b
|otherwise fib_help (n-1) b (a+b)
Note: I am writing the code in Notepad++ and I have changed the settings so that when I TAB it created 4 whitespaces instead of a tab character (like it should be I guess)
No, Haskell indentation is not like Python.
Haskell is not about indentation levels, it's all about making things line up with other things.
where fib_help n a b
In this example you have where
, and the following token is not {
. This activates layout mode (i.e. whitespace sensitive parsing). The next token (fib_help
) sets the start column for the following block:
where fib_help n a b
-- ^
-- | this is "column 0" for the current block
The next line is:
|n<=1 = b
The first token (|
) is indented less than "column 0", which implicitly closes the block.
Your code is parsed as if you had written
fib n = fib_help n 0 1
where { fib_help n a b }
|n<=1 = b
|otherwise fib_help (n-1) b (a+b)
This is several syntax errors: The where
block is missing a =
, and you can't start a new declaration with |
.
Solution: Indent everything that should be part of the where
block more than the first token after where
. For example:
fib n = fib_help n 0 1
where fib_help n a b
|n<=1 = b
|otherwise = fib_help (n-1) b (a+b)
Or:
fib n = fib_help n 0 1
where
fib_help n a b
|n<=1 = b
|otherwise = fib_help (n-1) b (a+b)
Or:
fib n = fib_help n 0 1 where
fib_help n a b
|n<=1 = b
|otherwise = fib_help (n-1) b (a+b)