2

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.

4
  • 3
    The code compiles fine (well, not really, since x has type Float and your type signature indicates it should have type Floating a => a) but there is no parse error, on that line or any other. Commented Jan 18, 2014 at 4:07
  • 3
    I'm betting it's an indentation problem, but can you give an example of a valid value of linea? Commented Jan 18, 2014 at 4:09
  • Thanks, it was, in fact, an indentation problem. I'm beginner in Haskell. Commented Jan 18, 2014 at 4:22
  • 2
    Indentation problem is very popular. If you want to forget about it, I advice you to use emacs + haskell-mode if you like emacs. If you don't, this is a good point to start, because emacs is pretty awesome. Anyway, there are even few options for vim. If you don't like them both, there is a plugin for sublime text. But there is one more choice: haskell web ide. It's really great :) Commented Jan 18, 2014 at 5:32

1 Answer 1

5

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
Sign up to request clarification or add additional context in comments.

9 Comments

Nearly everyone considers the proper approach to be not using tabs.
@Carl, Sorry, I should have made it clearer that my editor converts tabs to 4 spaces. Python is my primary language so that's pretty much beaten into me already. :)
In that case, the rule is simple: every declaration within a where block needs to start in the same column. Whatever column the first declaration starts in, the remaining declarations need to align to it.
That's the same rule for everything else that uses layout, by the way - multiple declarations in a let, multiple statements in a do, etc. Just align them to all match the first one, wherever you put the first one.
@Carl: Good to know, thanks. I think I shouldn't have any more problems now that I found out about the syntax highlighting issue I edited into my answer (I never noticed before because Python only ever aligns for the beginning of a line, where variable character widths never affect anything)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.