{-# LANGUAGE DeriveGeneric #-}
module CardParts.Suits(Suit(..), parseSuit) where
import Data.List (elemIndex)
import Data.Char ( toLower, isDigit, digitToInt )
import GHC.Generics (Generic)
import Data.Aeson (FromJSON)
import Data.Aeson.Types (ToJSON)
data Suit = Hearts
| Diamonds
| Clubs
| Spades deriving (Suit -> Suit -> Bool
(Suit -> Suit -> Bool) -> (Suit -> Suit -> Bool) -> Eq Suit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Suit -> Suit -> Bool
$c/= :: Suit -> Suit -> Bool
== :: Suit -> Suit -> Bool
$c== :: Suit -> Suit -> Bool
Eq, Int -> Suit -> ShowS
[Suit] -> ShowS
Suit -> String
(Int -> Suit -> ShowS)
-> (Suit -> String) -> ([Suit] -> ShowS) -> Show Suit
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Suit] -> ShowS
$cshowList :: [Suit] -> ShowS
show :: Suit -> String
$cshow :: Suit -> String
showsPrec :: Int -> Suit -> ShowS
$cshowsPrec :: Int -> Suit -> ShowS
Show, Int -> Suit
Suit -> Int
Suit -> [Suit]
Suit -> Suit
Suit -> Suit -> [Suit]
Suit -> Suit -> Suit -> [Suit]
(Suit -> Suit)
-> (Suit -> Suit)
-> (Int -> Suit)
-> (Suit -> Int)
-> (Suit -> [Suit])
-> (Suit -> Suit -> [Suit])
-> (Suit -> Suit -> [Suit])
-> (Suit -> Suit -> Suit -> [Suit])
-> Enum Suit
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Suit -> Suit -> Suit -> [Suit]
$cenumFromThenTo :: Suit -> Suit -> Suit -> [Suit]
enumFromTo :: Suit -> Suit -> [Suit]
$cenumFromTo :: Suit -> Suit -> [Suit]
enumFromThen :: Suit -> Suit -> [Suit]
$cenumFromThen :: Suit -> Suit -> [Suit]
enumFrom :: Suit -> [Suit]
$cenumFrom :: Suit -> [Suit]
fromEnum :: Suit -> Int
$cfromEnum :: Suit -> Int
toEnum :: Int -> Suit
$ctoEnum :: Int -> Suit
pred :: Suit -> Suit
$cpred :: Suit -> Suit
succ :: Suit -> Suit
$csucc :: Suit -> Suit
Enum, Suit
Suit -> Suit -> Bounded Suit
forall a. a -> a -> Bounded a
maxBound :: Suit
$cmaxBound :: Suit
minBound :: Suit
$cminBound :: Suit
Bounded, (forall x. Suit -> Rep Suit x)
-> (forall x. Rep Suit x -> Suit) -> Generic Suit
forall x. Rep Suit x -> Suit
forall x. Suit -> Rep Suit x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Suit x -> Suit
$cfrom :: forall x. Suit -> Rep Suit x
Generic)
instance FromJSON Suit
instance ToJSON Suit
parseSuit :: Char -> Either String Suit
parseSuit :: Char -> Either String Suit
parseSuit Char
symbol = case Char
symbol Char -> String -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
`elemIndex` String
suitSymbols of
Maybe Int
Nothing -> String -> Either String Suit
forall a b. a -> Either a b
Left (String -> Either String Suit) -> String -> Either String Suit
forall a b. (a -> b) -> a -> b
$ String
"There is no card suit marked as " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Char -> String
forall a. Show a => a -> String
show Char
symbol
Just Int
index -> Suit -> Either String Suit
forall a b. b -> Either a b
Right (Int -> Suit
forall a. Enum a => Int -> a
toEnum Int
index :: Suit)
where
allSuits :: [Suit]
allSuits :: [Suit]
allSuits = [Suit
forall a. Bounded a => a
minBound .. Suit
forall a. Bounded a => a
maxBound] :: [Suit]
suitSymbols :: [Char]
suitSymbols :: String
suitSymbols = [Char -> Char
toLower (Char -> Char) -> (Suit -> Char) -> Suit -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Char
forall a. [a] -> a
head (String -> Char) -> (Suit -> String) -> Suit -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Suit -> String
forall a. Show a => a -> String
show (Suit -> Char) -> Suit -> Char
forall a b. (a -> b) -> a -> b
$ Suit
s | Suit
s <- [Suit]
allSuits]