0

I'm learning Haskell and keep getting these indentation errors when I try to define functions over multiple lines in GHCi. Here's an attempt to redefine the elem function:

λ: :{
| let elem' x xs
|     | null xs = False
|     | x == head xs = True
|     | otherwise = elem' x (tail xs)
| :}

<interactive>:15:5: error:
    parse error (possibly incorrect indentation or mismatched brackets)

Do the = signs somehow need to be aligned?

duplode
  • 33,731
  • 7
  • 79
  • 150
dsaxton
  • 995
  • 2
  • 10
  • 23
  • You have to indent it at least one space further so it’s “inside” the definition and not just at the same level. – Ry- Apr 09 '17 at 03:40

2 Answers2

2

You need to indent the guards further. If you leave them at the same indentation than the elem' name, GHC(i) will attempt to parse them as additional definitions within the let-block, and not as part of the definition of elem:

let elem' x xs
        | null xs = False
        | x == head xs = True
        | otherwise = elem' x (tail xs)

If you are using GHC 8 or above, you don't need a let for defining things in GHCi, so this (between :{ and :}, as before) will just work:

elem' x xs
    | null xs = False
    | x == head xs = True
    | otherwise = elem' x (tail xs)
duplode
  • 33,731
  • 7
  • 79
  • 150
  • Got it, thanks. This seems to make coding in ghci pretty cumbersome though. Are there any tricks or tools for making this a bit easier? – dsaxton Apr 09 '17 at 03:51
  • @dsaxton The indentation rules, including this one involving `let`, are the same in GHCi and elsewhere. One alternative is using explicit braces and semicolons -- while I don't think it actually improves things, it is ocasionally handy if you want to enter something relatively short as a one-liner in the prompt. What I often do instead is typing multi-line definitions in a GVim window (or some other lightweight editor) and pasting them between `:{` and `:}` in GHCi. (Also note that, if you want to golf it, the linebreaks are actually optional when using guards.) – duplode Apr 09 '17 at 04:12
0

A let indented like this

let elem' x xs
    | null xs = False
    | x == head xs = True
    | otherwise = elem' x (tail xs)

is a let with four entries much like

let x1 = ...
    x2 = ...
    x3 = ...
    x4 = ...

if you want to continue a previous entry, rather than starting a new one, you should indent it more. The rule is the same in source files and in GHCi. The indentation rule might look a bit mysterious at the beginning but it's actually fairly simple.

Community
  • 1
  • 1
chi
  • 111,837
  • 3
  • 133
  • 218