7
votes

From where can I get complete set of Indentation rules for Haskell code writing?

Past SO questions which are similar to my following question has led me to ask above question. What are the reasons behind the error message: parse error on input 'something'?

Error message I got:

baby.hs:103:2: parse error on input `myList'(error in this line)

Code I am trying to compile:

myList = ["aeroplane", "Aeroplane", "AeRoPlAne", "helicopter", "HELICOPTER", "Zebra"]
quicksort :: (Ord a) => [a] -> [a]  
quicksort [] = []  
quicksort (x:xs) =
let smallerSorted = quicksort [a | a <- xs, a <= x]  
biggerSorted = quicksort [a | a <- xs, a > x]  
in smallerSorted ++ [x] ++ biggerSorted

Edit by Optimight:

I shifted the code in the question to new .hs file and tried to compile it. Still similar error message remains. Details below:

Error
quickSort.hs:5:62: parse error on input `=' Failed, modules loaded: none. (0.02 secs, 0 bytes)

Code quicksort :: (Ord a) => [a] -> [a]
quicksort [] = [] quicksort (x:xs) = let smallerSorted = quicksort [a | a <- xs, a <= x]
biggerSorted = quicksort [a | a <- xs, a > x]
in smallerSorted ++ [x] ++ biggerSorted
myList = ["aeroplane", "Aeroplane", "AeRoPlAne", "helicopter", "HELICOPTER", "Zebra", "America"]

2
Is line 103 the list defining myList? What are the lines preceding it?dave4420
@dave4420 Sir, I am learning from "Learn-you-a-haskell" and keeping my all code samples into same file i.e. baby.hs . Preceding lines include those code samples.Optimight
I am still clueless that how to avoid this error.Optimight

2 Answers

12
votes

At least for standard Haskell (without language extensions), the layout rules are explained in Section 10.3 of the Haskell 2010 report.

The report may be a bit formal for your taste. Various tutorials and textbooks on Haskell have some more informal explanations of the layout rules, for example the Haskell Wikibook.

In your particular case, the error message points to line 103, but you are only pasting a couple of lines. I can see that at least the indentation of the let-in construct is broken. You should write something like the following:

xs = ["aeroplane", "Aeroplane", "AeRoPlAne", "helicopter", "HELICOPTER", "Zebra"]
quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) = let smallerSorted = quicksort [a | a <- xs, a <= x]
                       biggerSorted = quicksort [a | a <- xs, a > x]
                   in smallerSorted ++ [x] ++ biggerSorted
3
votes

If I understood you correctly easiest way to avoid this problem is by writing single do and let like this:

fName = do
  expression1 = ...
  exp2 ...

fName param = let
  exp1 = ...
  exp2 = ...
  exp3 = ...
  in ...        -- can be indented more if you want

Main point here is that first indent at exp1 is easy to spot and maintain in every new line.




And here's copy/paste from my learning sheets. It's not much but might help someone. If anyone notice anything wrong/false please correct me.

tabs or spaces indicate BLOCK, like {com1; com2} in C++

Offside rule: At beginning of a source file, first top level declaration or definition can start in any column. Every subsequent top level declaration must have same indentation!

LET IN, WHERE remembers indentation of next token it sees. If empty line, or indentation is further to right, it continue previous line. If same indentation, this is beginning of new item in same block.

win tab 4 spc, unix tab 8 spaces Use spaces instead tab!!!

line1... 
   continue line 1 -- as long it doesn't start at same indent as line1
   3spaces would indicate block with line 1!
   line4 same block
   same indent is same line1 block
   all indents for BLOCK must be same.

line8...    -- is new block and end of line1 block
   positon of first column in block is start

line 1
 cont line1
  cont line 1
   cont line 1
    block1  -- would be cont line 1
    block1  --  if not for this block1 at same indent


Bad way:
do
  action0
  if condition
  then action1
  else action2
  action3

Good way:
do
  action0
  if condition
    then action1
    else action2
  action3