Reputation: 83
data Card = Card CardValue Suit deriving (Eq)
If I'm given a Card I want to determine which Suit this card is
I have tried using guards, but I'm still unsure on how to use them correctly. If I were to write pseudocode of the kind of thing I'm trying to do it would be along the lines of
if s == D
then D
else if s == D
then D
This is how much I've done, like I said I tried to use guards, but I got an error "parse error on input '|' when I used the following code
suitOf :: Card -> Suit
suitOf (Card _ s) = s
| s == D = D
| s == S = S
| otherwise = error "Invalid"
What is it that I'm doing wrong? The logic is fairly simple, I'm just not familiar with the syntax of haskell yet
Upvotes: 1
Views: 78
Reputation: 532448
I'm not sure why there would be an invalid case, but for only three possibilities, I would just write separate equations for each.
suitOf :: Card -> Suit
suitOf (Card _ D) = D
suitOf (Card _ S) = S
suitOf (Card _ _) = error "Invalid"
Without the error case, it is of course just
suitOf :: Card -> Suit
suitOf (Card _ s) = s
and with record syntax you don't even need to define the function yourself:
data Card = Card { rankOf :: CardValue, suitOf :: Suit } deriving (Eq)
Upvotes: 3
Reputation: 1705
You're looking for the case
expression (sometimes called match
in other languages):
data Suit = Diamond | Spade | Club | Heart deriving (Eq, Ord)
data Card = Card CardValue Suit deriving (Eq)
suitOf :: Card -> Suit
suitOf (Card _ s) =
case s of
Diamond -> Diamond
Spade -> Spade
_ -> error "Invalid"
where the _
pattern matches all non-matched input -- IIRC case expressions require all patterns to be matched or it'll error, but check me on that.
Note that this works with string literals as the case match patterns too:
toSuit :: String -> Suit
toSuit s =
case s of
"Diamond" -> Diamond
"Spade" -> Spade
_ -> error "Invalid"
Of course if you weren't going to test for just those two cases you'd merely return the suit directly:
suitOf :: Card -> Suit
suitOf (Card _ s) = s
:)
Upvotes: 4
Reputation: 1528
The problem is that you wrote
suitOf (Card _ s) = s
You don't write the equals sign on the first line of the function, only after each guard. If you change that line to
suitOf (Card _ s)
it should work. Additionally, this will only work if Suit is a type synonym for [Char]
(which I assume it is, but just something to check).
Upvotes: 3