{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}

module ROC.ID.Gender
  ( Gender (..)
  , printGender
  , randomGender
  ) where

import Control.Monad.Random.Class
    ( MonadRandom (..) )
import Data.Text
    ( Text )
import GHC.Generics
    ( Generic )

import ROC.ID.Language
import ROC.ID.Utilities

-- | A person's gender, encodable within an ROC identification number.
--
data Gender = Male | Female
  deriving (Gender
Gender -> Gender -> Bounded Gender
forall a. a -> a -> Bounded a
$cminBound :: Gender
minBound :: Gender
$cmaxBound :: Gender
maxBound :: Gender
Bounded, Int -> Gender
Gender -> Int
Gender -> [Gender]
Gender -> Gender
Gender -> Gender -> [Gender]
Gender -> Gender -> Gender -> [Gender]
(Gender -> Gender)
-> (Gender -> Gender)
-> (Int -> Gender)
-> (Gender -> Int)
-> (Gender -> [Gender])
-> (Gender -> Gender -> [Gender])
-> (Gender -> Gender -> [Gender])
-> (Gender -> Gender -> Gender -> [Gender])
-> Enum Gender
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 :: Gender -> Gender
succ :: Gender -> Gender
$cpred :: Gender -> Gender
pred :: Gender -> Gender
$ctoEnum :: Int -> Gender
toEnum :: Int -> Gender
$cfromEnum :: Gender -> Int
fromEnum :: Gender -> Int
$cenumFrom :: Gender -> [Gender]
enumFrom :: Gender -> [Gender]
$cenumFromThen :: Gender -> Gender -> [Gender]
enumFromThen :: Gender -> Gender -> [Gender]
$cenumFromTo :: Gender -> Gender -> [Gender]
enumFromTo :: Gender -> Gender -> [Gender]
$cenumFromThenTo :: Gender -> Gender -> Gender -> [Gender]
enumFromThenTo :: Gender -> Gender -> Gender -> [Gender]
Enum, Gender -> Gender -> Bool
(Gender -> Gender -> Bool)
-> (Gender -> Gender -> Bool) -> Eq Gender
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Gender -> Gender -> Bool
== :: Gender -> Gender -> Bool
$c/= :: Gender -> Gender -> Bool
/= :: Gender -> Gender -> Bool
Eq, (forall x. Gender -> Rep Gender x)
-> (forall x. Rep Gender x -> Gender) -> Generic Gender
forall x. Rep Gender x -> Gender
forall x. Gender -> Rep Gender x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Gender -> Rep Gender x
from :: forall x. Gender -> Rep Gender x
$cto :: forall x. Rep Gender x -> Gender
to :: forall x. Rep Gender x -> Gender
Generic, Eq Gender
Eq Gender =>
(Gender -> Gender -> Ordering)
-> (Gender -> Gender -> Bool)
-> (Gender -> Gender -> Bool)
-> (Gender -> Gender -> Bool)
-> (Gender -> Gender -> Bool)
-> (Gender -> Gender -> Gender)
-> (Gender -> Gender -> Gender)
-> Ord Gender
Gender -> Gender -> Bool
Gender -> Gender -> Ordering
Gender -> Gender -> Gender
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 :: Gender -> Gender -> Ordering
compare :: Gender -> Gender -> Ordering
$c< :: Gender -> Gender -> Bool
< :: Gender -> Gender -> Bool
$c<= :: Gender -> Gender -> Bool
<= :: Gender -> Gender -> Bool
$c> :: Gender -> Gender -> Bool
> :: Gender -> Gender -> Bool
$c>= :: Gender -> Gender -> Bool
>= :: Gender -> Gender -> Bool
$cmax :: Gender -> Gender -> Gender
max :: Gender -> Gender -> Gender
$cmin :: Gender -> Gender -> Gender
min :: Gender -> Gender -> Gender
Ord, Int -> Gender -> ShowS
[Gender] -> ShowS
Gender -> [Char]
(Int -> Gender -> ShowS)
-> (Gender -> [Char]) -> ([Gender] -> ShowS) -> Show Gender
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Gender -> ShowS
showsPrec :: Int -> Gender -> ShowS
$cshow :: Gender -> [Char]
show :: Gender -> [Char]
$cshowList :: [Gender] -> ShowS
showList :: [Gender] -> ShowS
Show)

-- | Pretty-print the specified 'Gender'.
--
printGender :: Language -> Gender -> Text
printGender :: Language -> Gender -> Text
printGender = \case
  Language
English -> Gender -> Text
printGenderEnglish
  Language
Chinese -> Gender -> Text
printGenderChinese

printGenderEnglish :: Gender -> Text
printGenderEnglish :: Gender -> Text
printGenderEnglish = \case
  Gender
Male   -> Text
"Male"
  Gender
Female -> Text
"Female"

printGenderChinese :: Gender -> Text
printGenderChinese :: Gender -> Text
printGenderChinese = \case
  Gender
Male   -> Text
"男性"
  Gender
Female -> Text
"女性"

-- | Generate a random 'Gender'.
--
randomGender :: MonadRandom m => m Gender
randomGender :: forall (m :: * -> *). MonadRandom m => m Gender
randomGender = m Gender
forall a (m :: * -> *). (MonadRandom m, Bounded a, Enum a) => m a
randomBoundedEnum