Search code examples
functionhaskellsyntaxdefinitionguard-clause

Haskell gets confused with horizontal lines


I tried to practice haskell a bit but I didn't get the following code to work:

rems :: Int -> [Int] -> [Int]
rems _ [] = []
rems k (x:xs)
  | k == x = rems k xs
  | otherwise [x] ++ rems k xs



main = print $
  rems 3 [5, 3, 2]

This function removes every k from a list x if you call it rems k x. I know that it should be working because we wrote it down in university.

I'm using this IDE: https://repl.it/languages/haskell


Solution

  • It might be useful to know that otherwise isn't a keyword or special symbol like =, it's actually simply a boolean value defined in the prelude as True. I.e., a guard with otherwise works syntactically the same as any other guard, just the condition is trivial. You might also write it

    rems _ [] = []
    rems k (x:xs)
      | k == x  = rems k xs
      | True    = [x] ++ rems k xs
    

    The alignment I chose above (all = aligned and at least two spaces away from the guard-condition) is completely a matter of taste, but I think it helps avoiding confusion like the one you've found yourself in.

    BTW, [x] ++ ... can be shortened to x : .... The preferred form of writing the function is

    rems _ [] = []
    rems k (x:xs)
      | k==x       = rems k xs
      | otherwise  = x : rems k xs
    

    Most people align the =s but use only one space. That's ok, but IMO k == x = res looks deceptive with all those equals-characters, and k and x further away from each other than from the result. k==x = res seems tidier.