
I'm having some trouble defining an implementation for "Read". I know I could model a card more simply as an unconstrained tuplet, but I'm trying to learn new things about haskell as I go. module Card.Card ( Suit(..) ,Card(..) ) where data Suit = Club | Spade | Diamond | Heart deriving (Eq, Ord, Show, Read, Bounded, Enum) data Card = Card { suit :: Suit , rank :: Int } deriving (Ord, Bounded, Eq) instance Show Card where show Card { suit = Club, rank = a } = show a ++ "c" show Card { suit = Spade, rank = a } = show a ++ "s" show Card { suit = Heart, rank = a } = show a ++ "h" show Card { suit = Diamond, rank = a } = show a ++ "d" instance Read Card where readsPrec (a:b) = Card{ suit=(toSuit a), rank=(read b) } where toSuit s | s=='c' = Club | s=='s' = Spade | s=='d' = Diamond | s=='h' = Heart The error is: Card/Card.hs:24:12: Couldn't match expected type `Int' against inferred type `[a]' In the pattern: a : b In the definition of `readsPrec': readsPrec (a : b) = Card {suit = (toSuit a), rank = (read b)} where toSuit s | s == 'c' = Club | s == 's' = Spade | s == 'd' = Diamond | s == 'h' = Heart In the instance declaration for `Read Card' Where am I going wrong? Thanks, Peter

On Sunday 11 September 2011, 20:32:32, Peter Hall wrote:
instance Show Card where show Card { suit = Club, rank = a } = show a ++ "c" show Card { suit = Spade, rank = a } = show a ++ "s" show Card { suit = Heart, rank = a } = show a ++ "h" show Card { suit = Diamond, rank = a } = show a ++ "d"
instance Read Card where readsPrec (a:b) = Card{ suit=(toSuit a), rank=(read b) } where toSuit s
| s=='c' = Club | s=='s' = Spade | s=='d' = Diamond | s=='h' = Heart
The error is: Card/Card.hs:24:12: Couldn't match expected type `Int' against inferred type `[a]' In the pattern: a : b In the definition of `readsPrec': readsPrec (a : b) = Card {suit = (toSuit a), rank = (read b)} where toSuit s | s == 'c' = Club
| s == 's' = Spade | s == 'd' = Diamond | s == 'h' = Heart
In the instance declaration for `Read Card'
Where am I going wrong?
readsPrec takes a precedence level as first argument (to determine whether parentheses are necessary). If you want to ignore that for the moment, changing your definition to readsprec _ (a:b) = ... should work. However, you show cards in the order rank, suit, but you read them suit, rank. It would be better to be consistent with read and show (so that read (show x) == x).

Thanks,
Good spot on the order. I'll get to that, but I still didn't have
success with your other suggestion.
readsPrec _ (a:b) = Card{ suit=(toSuit a), rank=(read b) }
The error is:
Card/Card.hs:24:21:
Couldn't match expected type `[(Card, String)]'
against inferred type `Card'
In the expression: Card {suit = (toSuit a), rank = (read b)}
In the definition of `readsPrec':
readsPrec _ (a : b)
= Card {suit = (toSuit a), rank = (read b)}
where
toSuit s | s == 'c' = Club
| s == 's' = Spade
| s == 'd' = Diamond
| s == 'h' = Heart
In the instance declaration for `Read Card'
Peter
On Sun, Sep 11, 2011 at 8:05 PM, Daniel Fischer
On Sunday 11 September 2011, 20:32:32, Peter Hall wrote:
instance Show Card where show Card { suit = Club, rank = a } = show a ++ "c" show Card { suit = Spade, rank = a } = show a ++ "s" show Card { suit = Heart, rank = a } = show a ++ "h" show Card { suit = Diamond, rank = a } = show a ++ "d"
instance Read Card where readsPrec (a:b) = Card{ suit=(toSuit a), rank=(read b) } where toSuit s
| s=='c' = Club | s=='s' = Spade | s=='d' = Diamond | s=='h' = Heart
The error is: Card/Card.hs:24:12: Couldn't match expected type `Int' against inferred type `[a]' In the pattern: a : b In the definition of `readsPrec': readsPrec (a : b) = Card {suit = (toSuit a), rank = (read b)} where toSuit s | s == 'c' = Club
| s == 's' = Spade | s == 'd' = Diamond | s == 'h' = Heart
In the instance declaration for `Read Card'
Where am I going wrong?
readsPrec takes a precedence level as first argument (to determine whether parentheses are necessary).
If you want to ignore that for the moment, changing your definition to
readsprec _ (a:b) = ...
should work.
However, you show cards in the order rank, suit, but you read them suit, rank. It would be better to be consistent with read and show (so that read (show x) == x).

On Sunday 11 September 2011, 23:27:53, Peter Hall wrote:
Thanks, Good spot on the order. I'll get to that, but I still didn't have success with your other suggestion.
Oops, yes. readsPrec returns a list of pairs, [(parsed value, remaining input)], so readsPrec _ (a:b) = [(Card{suit = toSuit a, rank = r}, trl) | (r, trl) <- reads b] where toSuit 'c' = Club ...

Thanks, I was just responding, with:
readsPrec _ (b:a:rest) = [(Card{ suit=(toSuit a), rank=(read [b]) }, rest)]
Thanks for your help!
Peter
On Sun, Sep 11, 2011 at 10:56 PM, Daniel Fischer
On Sunday 11 September 2011, 23:27:53, Peter Hall wrote:
Thanks, Good spot on the order. I'll get to that, but I still didn't have success with your other suggestion.
Oops, yes.
readsPrec returns a list of pairs, [(parsed value, remaining input)],
so
readsPrec _ (a:b) = [(Card{suit = toSuit a, rank = r}, trl) | (r, trl) <- reads b] where toSuit 'c' = Club ...

I see this has been answered, but since someone else may be learning too I thought I would share. I have always used deriving for Read so I was unsure. This post gave me the push to go hunt it down. A very quick grep for "instance Read" in the ghc lib sources and I found: instance Read Int64 where readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s] In the Int.hs source. The other ints are similar. So like Daniel I ended up with a definition based on reads once I experimented quickly.
participants (3)
-
Daniel Fischer
-
Peter Hall
-
Sean Perry