1
isValid :: Position -> Bool
isValid Position(x _) = x
isValid Position(_ y) = y
    | x 'elem' ['a'..'h'] && y 'elem' [1..8] = True
    | otherwise = False

I keep getting this error error: Parse error in pattern: x I am trying to write a function that tells me whether a given poisition is valid or not. Where x is ['a'..'h'] and y is [1..8]

Dave
  • 83
  • 1
  • 7

3 Answers3

3

As explained here: Syntax error on 'mod' Haskell

The syntax for using a named function as an infix operator uses backticks (grave accents, U+0060), not apostrophes:

    | x `elem` ['a'..'h'] && y `elem` [1..8] = True
        ------                 ------
    | otherwise = False

In addition, Position(x _) and Position(_ y) are not valid patterns—you probably intended to use (Position x _) and (Position x y). Note the x, since x is not in scope in the equation you wrote for (Position _ y).

(Position x _) will match all positions, so I suspect you intended:

isValid :: Position -> Bool
isValid (Position x y)
    | x `elem` ['a'..'h'] && y `elem` [1..8] = True
    | otherwise = False

Or more simply:

isValid :: Position -> Bool
isValid (Position x y) = x `elem` ['a'..'h'] && y `elem` [1..8]
Jon Purdy
  • 53,300
  • 8
  • 96
  • 166
3

I keep getting this error error: Parse error in pattern: x I am trying to write a function that tells me whether a given position is valid or not. Where x is ['a'..'h'] and y is [1..8].

The other answers already discussed what is wrong: you used a guard in the clause where there is no bounded x:

isValid Position(_ y) = y

and furthermore you use quotes instead of backticks with the elem function:

x 'elem' ['a'..'h']

So a rigorous fix would be:

isValid :: Position -> Bool
isValid (Position x y)
    | x `elem` ['a'..'h'] && y `elem` [1..8] = True
    | otherwise = False

Since we actually return the result of the guard, we do not need to use guards and can collapse the guards into one expression:

isValid :: Position -> Bool
isValid (Position x y) = x `elem` ['a'..'h'] && y `elem` [1..8]

Nevertheless since we here work with ranges and the second range are integers, we do not have to use elem on a range, we can use:

isValid :: Position -> Bool
isValid (Position x y) = 'a' <= x && x <= 'h' && 1 <= y && y <= 8

For such small ranges, there will probably not be that much impact on performance, but elem works in O(n) worst case, whereas the two bounds checks work in O(1).

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
2

In

    | x 'elem' ['a'..'h'] && y 'elem' [1..8] = True

x is unbound. It doesn't appear at all in

isValid Position(_ y) = y

in particular. Also, you probably meant to use `elem`, and not 'elem'.

I am trying to write a function that tells me whether a given poisition is valid or not. Where x is ['a'..'h'] and y is [1..8]

You didn't write the definition of Position, but it seems like this would be something like

data Position = Position Int Int                                                                                                                                     

isValid :: Position -> Bool
isValid (Position x y) = x `elem` ['a'..'h'] && y `elem` [1..8]

(which builds for me).

Antal Spector-Zabusky
  • 36,191
  • 7
  • 77
  • 140
Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
  • @Dave You also have another error, in using `'elem'` instead of `\`elem\``, and another one besides that. See updated answer. – Ami Tavory Jun 01 '17 at 05:47
  • 3
    @Dave As you seem new to the site (at least by your rep), note that you can accept a single answer, but, independently upvote whatever answers helped you. JonPurdy seems to have answered your question too correctly, so you might want to upvote it as thanks. – Ami Tavory Jun 01 '17 at 05:58