{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} {-| The "Data.CAProvinceCodes" module is used for enumerating, and rendering the codes for Canadian Provinces and Territories. It is meant to be qualified when imported: @ import qualified Data.CAProvinceCodes as CAProvinces @ -} module Data.CAProvinceCodes ( Code(..) , all , toName , fromName , isProvince , isTerritory ) where import Data.Aeson ( ToJSON , FromJSON ) import qualified Data.Text as T import GHC.Generics ( Generic ) import Prelude hiding ( all ) {-| A Canadian Province/Territory Code from . -} data Code = AB -- ^ Alberta | BC -- ^ British Columbia | MB -- ^ Manitoba | NB -- ^ New Brunswick | NL -- ^ Newfoundland And Labrador | NS -- ^ Nova Scotia | NT -- ^ Northwest Territories | NU -- ^ Nunavut | ON -- ^ Ontario | PE -- ^ Prince Edward Island | QC -- ^ Quebec | SK -- ^ Saskatchewan | YT -- ^ Yukon deriving (Show, Read, Eq, Enum, Bounded, Generic) instance ToJSON Code instance FromJSON Code {-| A list of every Province/Territory Code. -} all :: [Code] all = enumFrom minBound {-| Render a `Code` to it's English name. -} toName :: Code -> T.Text toName c = case c of AB -> "Alberta" BC -> "British Columbia" MB -> "Manitoba" NB -> "New Brunswick" NL -> "Newfoundland And Labrador" NS -> "Nova Scotia" NT -> "Northwest Territories" NU -> "Nunavut" ON -> "Ontario" PE -> "Prince Edward Island" QC -> "Quebec" SK -> "Saskatchewan" YT -> "Yukon" {-| Parse a `Code` from an English name. This is case-insensitive. -} fromName :: T.Text -> Maybe Code fromName n = case T.toLower n of "alberta" -> Just AB "british columbia" -> Just BC "manitoba" -> Just MB "new brunswick" -> Just NB "newfoundland and labrador" -> Just NL "nova scotia" -> Just NS "northwest territories" -> Just NT "nunavut" -> Just NU "ontario" -> Just ON "prince edward island" -> Just PE "quebec" -> Just QC "saskatchewan" -> Just SK "yukon" -> Just YT _ -> Nothing {-| Does the `Code` denote a Province? -} isProvince :: Code -> Bool isProvince = not . isTerritory {-| Does the `Code` denote a Territory? -} isTerritory :: Code -> Bool isTerritory = (`elem` [NT, NU, YT])