Why shouldn’t I mix tabs and spaces?

The problem is twofold. First of all, Haskell is indentation sensitive, e.g. the following code isn’t valid:

example = (a, b)
  where
    a = "Hello"
     b = "World"

Both bindings need to be indented with the same number of spaces/tabs (see off-side rule). While it’s obvious in this case, it’s rather hidden in the following one, where I denote a space by · and a tab by »:

example = (a, b)
··where
····a = "Hello"
»   b = "World"

This will look like valid Haskell code if the editor will show tabs aligned to multiples by four. But it isn’t. Haskell tabs are aligned by multiples of eight, so the code will be interpreted like this:

example = (a, b)
··where
····a = "Hello"
»       b = "World"

Second, if you use only tabs, you can end up with a layout that doesn’t look right. For example, the following code looks correct if a tab gets displayed with six or more spaces (eight in this case):

example = (a, b)
»       where»  a = "Hello"
»       »       b = "World"

But in another editor that uses 4 spaces it won’t look right anymore:

example = (a, b)
»   where»  a = "Hello"
»   »   b = "World"

It’s still correct, though. However, someone who’s used to spaces might reindent b‘ binding with spaces and end up with a parser error.

If you enforce a code convention throughout your code that makes sure that you only use tabs at the beginning of a line and use a newline after where, let or do you can avoid some of the problems (see 11). However, current releases of GHC warn about tabs by default, because they have been a source of many parser errors in the past, so you probably want to get rid of them too.

See also

Leave a Comment