Facts-0.1: src/Facts/Geography/Countries.hs
{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
{-# OPTIONS_GHC -fwarn-missing-methods #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE ViewPatterns #-}
module Facts.Geography.Countries ( Country (..) --
, ISOAlpha2Code (..)
, ISOAlpha3Code (..)
, ISONumericCode
, UNFormalName
, UNShortName
, isoNumericCode
, shortEnglishCountryName
, formalEnglishCountryName
, isoAlpha2Code_for_country
, isoAlpha3Code_for_country
, country_for_isoAlpha2Code
, country_for_isoAlpha3Code
, isoNumericCode_for_country
, country_for_valid_isoNumericCode
, country_for_isoNumericCode
) where
import Data.Numerals.Decimal
import Facts.Geography.Countries.Internal.Splices
import Facts.Geography.Countries.Internal.Data
import Test.QuickCheck
import Test.QuickCheck.Gen
instance Show Country where
show = shortEnglishCountryName
-- | Maps a 'Country' to its ISO-3166-1 2-character code.
isoAlpha2Code_for_country :: Country -> ISOAlpha2Code
-- | Maps a 'Country' to its ISO-3166-1 3-character code.
isoAlpha3Code_for_country :: Country -> ISOAlpha3Code
-- | Maps a 'Country' to its ISO-3166-1 numeric code.
isoNumericCode_for_country :: Country -> ISONumericCode
-- | Maps an ISO-3166-1 2-character code to a 'Country'.
country_for_isoAlpha2Code :: ISOAlpha2Code -> Country
-- | Maps an ISO-3166-1 3-character code to a 'Country'.
country_for_isoAlpha3Code :: ISOAlpha3Code -> Country
country_code_by_country = _country_code_by_country
country_by_country_code = _country_by_country_code
country_name_by_country = _country_name_by_country
isoAlpha2Code_for_country = _isoAlpha2_for_country
isoAlpha3Code_for_country = _isoAlpha3_for_country
isoNumericCode_for_country = _isoNumeric_for_country
country_for_isoAlpha2Code = _country_for_isoAlpha2
country_for_isoAlpha3Code = _country_for_isoAlpha3
-- | The ISO Numeric Code space is not fully packed. Many codes are \"reserved\" or otherwise
-- unused. 'country_for_isoNumericCode' takes an 'ISONumericCode' and possibly returns a matching
-- 'Country'.
country_for_isoNumericCode :: ISONumericCode -> Maybe Country
country_for_isoNumericCode = (fmap country_for_valid_isoNumericCode) . validate_isoNumericCode
-- | 'country_for_valid_isoNumericCode' maps a valid 'ISONumericCode' to a 'Country'. Unfortunately,
-- this is a partial function. Use 'country_for_isoNumericCode' instead, unless you can guarantee
-- that the 'ISONumericCode' supplied to the query is valid.
country_for_valid_isoNumericCode :: ISONumericCode -> Country
country_for_valid_isoNumericCode = _country_for_isoNumeric
-- | 'shortEnglishCountryName' maps a Country to an ISO-3166-1 \"short name\". By the international
-- standard, these names are taken from the \"United Nations Terminology Bulletin Country Names\",
-- and \"Country and Region Codes for Statistical Use\" of the UN Statistics Division.
shortEnglishCountryName :: Country -> UNShortName
shortEnglishCountryName = _shortEnglishCountryName
-- | 'formalEnglishCountryName' maps a Country to an ISO-3166-1 \"formal name\". By the international
-- standard, these names are taken from the \"United Nations Terminology Bulletin Country Names\",
-- and \"Country and Region Codes for Statistical Use\" of the UN Statistics Division.
formalEnglishCountryName :: Country -> UNFormalName
formalEnglishCountryName = _formalEnglishCountryName
instance Arbitrary Country where arbitrary = elements [Afghanistan .. Zimbabwe]
newtype ValidCode = ValidCode ISOCountryCode deriving (Show)
instance Arbitrary ValidCode where arbitrary = elements . fmap (ValidCode) $ valid_iso_country_codes
prop_country_to_code_roundtrip :: Country -> Bool
prop_country_to_code_roundtrip country = (country_by_country_code . country_code_by_country $ country) == country
prop_code_to_country_roundtrip :: ValidCode -> Bool
prop_code_to_country_roundtrip (ValidCode code) = (country_code_by_country . country_by_country_code $ code) == code