{-# LANGUAGE DeriveAnyClass #-}
module Months
(
Month (..)
, CyclicEnum (..)
, makeMonth
) where
import Data.Char (toLower, toTitle)
import Test.QuickCheck (Arbitrary (..), elements)
import Text.Read (readMaybe)
class (Eq a, Enum a, Bounded a) => CyclicEnum a where
cpred :: a -> a
cpred a
x
| a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Bounded a => a
minBound = a
forall a. Bounded a => a
maxBound
| Bool
otherwise = a -> a
forall a. Enum a => a -> a
pred a
x
csucc :: a -> a
csucc a
x
| a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Bounded a => a
maxBound = a
forall a. Bounded a => a
minBound
| Bool
otherwise = a -> a
forall a. Enum a => a -> a
succ a
x
data Month
= January
| February
| March
| April
| May
| June
| July
| August
| September
| October
| November
| December
deriving (Month -> Month -> Bool
(Month -> Month -> Bool) -> (Month -> Month -> Bool) -> Eq Month
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Month -> Month -> Bool
== :: Month -> Month -> Bool
$c/= :: Month -> Month -> Bool
/= :: Month -> Month -> Bool
Eq, Eq Month
Eq Month
-> (Month -> Month -> Ordering)
-> (Month -> Month -> Bool)
-> (Month -> Month -> Bool)
-> (Month -> Month -> Bool)
-> (Month -> Month -> Bool)
-> (Month -> Month -> Month)
-> (Month -> Month -> Month)
-> Ord Month
Month -> Month -> Bool
Month -> Month -> Ordering
Month -> Month -> Month
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Month -> Month -> Ordering
compare :: Month -> Month -> Ordering
$c< :: Month -> Month -> Bool
< :: Month -> Month -> Bool
$c<= :: Month -> Month -> Bool
<= :: Month -> Month -> Bool
$c> :: Month -> Month -> Bool
> :: Month -> Month -> Bool
$c>= :: Month -> Month -> Bool
>= :: Month -> Month -> Bool
$cmax :: Month -> Month -> Month
max :: Month -> Month -> Month
$cmin :: Month -> Month -> Month
min :: Month -> Month -> Month
Ord, Int -> Month -> ShowS
[Month] -> ShowS
Month -> String
(Int -> Month -> ShowS)
-> (Month -> String) -> ([Month] -> ShowS) -> Show Month
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Month -> ShowS
showsPrec :: Int -> Month -> ShowS
$cshow :: Month -> String
show :: Month -> String
$cshowList :: [Month] -> ShowS
showList :: [Month] -> ShowS
Show, ReadPrec [Month]
ReadPrec Month
Int -> ReadS Month
ReadS [Month]
(Int -> ReadS Month)
-> ReadS [Month]
-> ReadPrec Month
-> ReadPrec [Month]
-> Read Month
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Month
readsPrec :: Int -> ReadS Month
$creadList :: ReadS [Month]
readList :: ReadS [Month]
$creadPrec :: ReadPrec Month
readPrec :: ReadPrec Month
$creadListPrec :: ReadPrec [Month]
readListPrec :: ReadPrec [Month]
Read, Int -> Month
Month -> Int
Month -> [Month]
Month -> Month
Month -> Month -> [Month]
Month -> Month -> Month -> [Month]
(Month -> Month)
-> (Month -> Month)
-> (Int -> Month)
-> (Month -> Int)
-> (Month -> [Month])
-> (Month -> Month -> [Month])
-> (Month -> Month -> [Month])
-> (Month -> Month -> Month -> [Month])
-> Enum Month
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Month -> Month
succ :: Month -> Month
$cpred :: Month -> Month
pred :: Month -> Month
$ctoEnum :: Int -> Month
toEnum :: Int -> Month
$cfromEnum :: Month -> Int
fromEnum :: Month -> Int
$cenumFrom :: Month -> [Month]
enumFrom :: Month -> [Month]
$cenumFromThen :: Month -> Month -> [Month]
enumFromThen :: Month -> Month -> [Month]
$cenumFromTo :: Month -> Month -> [Month]
enumFromTo :: Month -> Month -> [Month]
$cenumFromThenTo :: Month -> Month -> Month -> [Month]
enumFromThenTo :: Month -> Month -> Month -> [Month]
Enum, Month
Month -> Month -> Bounded Month
forall a. a -> a -> Bounded a
$cminBound :: Month
minBound :: Month
$cmaxBound :: Month
maxBound :: Month
Bounded, Bounded Month
Enum Month
Eq Month
Eq Month
-> Enum Month
-> Bounded Month
-> (Month -> Month)
-> (Month -> Month)
-> CyclicEnum Month
Month -> Month
forall a.
Eq a -> Enum a -> Bounded a -> (a -> a) -> (a -> a) -> CyclicEnum a
$ccpred :: Month -> Month
cpred :: Month -> Month
$ccsucc :: Month -> Month
csucc :: Month -> Month
CyclicEnum)
instance Arbitrary Month where
arbitrary :: Gen Month
arbitrary = [Month] -> Gen Month
forall a. [a] -> Gen a
elements [Month
forall a. Bounded a => a
minBound..Month
forall a. Bounded a => a
maxBound]
makeMonth :: String -> Maybe Month
makeMonth :: String -> Maybe Month
makeMonth = String -> Maybe Month
forall a. Read a => String -> Maybe a
readMaybe (String -> Maybe Month) -> ShowS -> String -> Maybe Month
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
capitalise
capitalise :: String -> String
capitalise :: ShowS
capitalise = ((Char -> Char) -> Char -> Char) -> [Char -> Char] -> ShowS
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Char -> Char) -> Char -> Char
forall a. a -> a
id (Char -> Char
toTitle (Char -> Char) -> [Char -> Char] -> [Char -> Char]
forall a. a -> [a] -> [a]
: (Char -> Char) -> [Char -> Char]
forall a. a -> [a]
repeat Char -> Char
toLower)