parse error on input `=' in Haskell

Adrian picture Adrian · Jan 18, 2014 · Viewed 10.5k times · Source

I wrote the following function in Haskell

coordenadas :: (Floating a) => String -> (a, a, a)
coordenadas linea = (x, y, z)
    where  (_ : xStr : yStr : zStr : _) = words linea
           x = read $ tail xStr :: Float
           y = read $ tail yStr :: Float
           z = read $ tail zStr :: Float

This function is meant to receive a string like "N1 X2 Y1 Z10" and produce a tuple like (2, 1, 10), but when I try to compile it, the compiler says that there's a parse error on input '=' in the line x = read $ tail xStr :: Float.

Does anyone know how to solve it?

Thanks for answering.

Answer

Free Monica Cellio picture Free Monica Cellio · Jan 18, 2014

I got it working:

coordinates :: String -> (Float, Float, Float)
coordinates line = (x,y,z)
    where   (_ : xStr : yStr : zStr : _) = words line
            x = read $ tail xStr :: Float
            y = read $ tail yStr :: Float
            z = read $ tail zStr :: Float

main = do
    let line = "test x1.0 y1.0 z1.0 test"
    print $ coordinates line

This outputs (1.0, 1.0, 1.0) as expected.

I'm kind of new to Haskell myself, so I have no idea why it's this picky about indentation (and would appreciate pointers from people who know more than I do!), but apparently the correct way is:

  • tab, where, tab again, then type the first line
  • tab 3 times, then line up future lines with that one

(NOTE: In my editor "tab" is "4 spaces", not a tab character)

EDIT: I think I just figured out why it was hard to line up on my end: syntax highlighting! My editor bolded "where", which made it wider, which made the correct indentation look incorrect. I actually confirmed this by turning off highlighting and it appears to work as long as the lines are aligned with each other.

This also means that this way probably avoids similar problems:

coordinates :: String -> (Float, Float, Float)
coordinates line = (x,y,z)
    where 
        (_ : xStr : yStr : zStr : _) = words line
        x = read $ tail xStr :: Float
        y = read $ tail yStr :: Float
        z = read $ tail zStr :: Float