diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,3 +19,6 @@
 
 ## **0.3.0.2** - 2026-05-07
 - new country supported: ISR
+
+## **0.4.0.0** - 2026-06-04
+- use ADT's for country codes and regions
diff --git a/holidays.cabal b/holidays.cabal
--- a/holidays.cabal
+++ b/holidays.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: holidays
-version: 0.3.0.2
+version: 0.4.0.0
 synopsis: Library for country public holidays
 description:
   Public holidays with Haskell.
diff --git a/src/Holidays.hs b/src/Holidays.hs
--- a/src/Holidays.hs
+++ b/src/Holidays.hs
@@ -2,26 +2,52 @@
 This module determines public holidays based on country code and year.
 -}
 module Holidays (
-  ISO_3166_1_Alpha_3,
-  Region,
+  ISO_3166_1_Alpha_3 (..),
+  Germany.GermanRegion (..),
   holidays,
   hday,
   Holiday (..),
+  mkCountryCode,
 )
 where
 
 import qualified Data.Set as S
+import qualified Data.Text as T
 import Data.Time
 import Holidays.Base
 import Holidays.DateTransform
-import qualified Holidays.Germany as DEU
-import qualified Holidays.Israel as ISR
-import qualified Holidays.Mozambique as MOZ
-import qualified Holidays.Namibia as NAM
-import qualified Holidays.SouthAfrica as ZAF
-import qualified Holidays.UnitedKingdom as GBR
-import qualified Holidays.UnitedStates as USA
+import qualified Holidays.Germany as Germany
+import qualified Holidays.Israel as Israel
+import qualified Holidays.Mozambique as Mozambique
+import qualified Holidays.Namibia as Namibia
+import qualified Holidays.SouthAfrica as SouthAfrica
+import qualified Holidays.UnitedKingdom as UnitedKingdom
+import qualified Holidays.UnitedStates as UnitedStates
 
+-- | 3-letter country codes.
+data ISO_3166_1_Alpha_3
+  = DEU (S.Set Germany.GermanRegion)
+  | GBR
+  | ISR
+  | MOZ
+  | NAM
+  | USA
+  | ZAF
+  deriving (Show)
+
+-- | Constructor for country code.
+mkCountryCode :: T.Text -> [T.Text] -> Maybe ISO_3166_1_Alpha_3
+mkCountryCode t regions =
+  case t of
+    "DEU" -> Just (DEU (Germany.mkGermanRegions regions))
+    "GBR" -> Just GBR
+    "ISR" -> Just ISR
+    "MOZ" -> Just MOZ
+    "NAM" -> Just NAM
+    "USA" -> Just USA
+    "ZAF" -> Just ZAF
+    _ -> Nothing
+
 {- |
 Returns a set of public holidays based on the country code (ISO_3166_1_Alpha_3) and a specific year.
 If a country is not supported an empty set is returned.
@@ -30,21 +56,20 @@
 Examples:
 
 @
-holidays \"DEU\" [\"BW\",\"BY\",\"BE\"] 2025 -- Germany and various regions
-holidays \"USA\" [] 2025
+holidays DEU (S.fromList [BW, BY ,BE]) 2025 -- Germany and various regions
+holidays USA 2025
 @
 -}
-holidays :: ISO_3166_1_Alpha_3 -> [Region] -> Year -> S.Set Holiday
-holidays countryCode regions year =
+holidays :: ISO_3166_1_Alpha_3 -> Year -> S.Set Holiday
+holidays countryCode year =
   case countryCode of
-    "DEU" -> DEU.holidays regions `apply` year
-    "GBR" -> GBR.holidays `apply` year
-    "ISR" -> S.union (ISR.holidays `apply` year) (ISR.sabbaths year)
-    "MOZ" -> MOZ.holidays `apply` year
-    "NAM" -> NAM.holidays `apply` year
-    "USA" -> USA.holidays `apply` year
-    "ZAF" -> ZAF.holidays `apply` year
-    _ -> S.empty
+    (DEU regions) -> Germany.holidays regions `apply` year
+    GBR -> UnitedKingdom.holidays `apply` year
+    ISR -> S.union (Israel.holidays `apply` year) (Israel.sabbaths year)
+    MOZ -> Mozambique.holidays `apply` year
+    NAM -> Namibia.holidays `apply` year
+    USA -> UnitedStates.holidays `apply` year
+    ZAF -> SouthAfrica.holidays `apply` year
 
 -- | Applies year and date transformations to holidays
 apply :: ([Year -> Holiday], [DateTransform]) -> Year -> S.Set Holiday
diff --git a/src/Holidays/Base.hs b/src/Holidays/Base.hs
--- a/src/Holidays/Base.hs
+++ b/src/Holidays/Base.hs
@@ -1,7 +1,5 @@
 module Holidays.Base (
   Holiday (..),
-  ISO_3166_1_Alpha_3,
-  Region,
   day,
   hday,
   nullDay,
@@ -10,12 +8,6 @@
 
 import qualified Data.Text as T
 import Data.Time
-
--- | 3-letter country codes.
-type ISO_3166_1_Alpha_3 = T.Text
-
--- | Custom regions for a country.
-type Region = T.Text
 
 data Holiday
   = Holiday
diff --git a/src/Holidays/Germany.hs b/src/Holidays/Germany.hs
--- a/src/Holidays/Germany.hs
+++ b/src/Holidays/Germany.hs
@@ -4,16 +4,71 @@
   https://publicholidays.de/
 --}
 module Holidays.Germany (
+  GermanRegion (..),
   holidays,
+  mkGermanRegions,
 ) where
 
+import Data.Maybe
+import qualified Data.Set as S
+import qualified Data.Text as T
 import Data.Time
 
 import Holidays.Base
 import Holidays.DateFinder
 import Holidays.DateTransform
 
-holidays :: [Region] -> ([Year -> Holiday], [DateTransform])
+-- | 2-letter german region.
+data GermanRegion
+  = BW
+  | BY
+  | BE
+  | BB
+  | HB
+  | HH
+  | HE
+  | MV
+  | NI
+  | NW
+  | RP
+  | SL
+  | SN
+  | ST
+  | SH
+  | TH
+  deriving (Eq, Ord, Show)
+
+mkGermanRegions :: [T.Text] -> S.Set GermanRegion
+mkGermanRegions ts =
+  foldr
+    ( \r acc ->
+        let gr = mkRegion r in if isJust gr then S.insert (fromJust gr) acc else acc
+    )
+    S.empty
+    ts
+
+mkRegion :: T.Text -> Maybe GermanRegion
+mkRegion t =
+  case t of
+    "BW" -> Just BW
+    "BY" -> Just BY
+    "BE" -> Just BE
+    "BB" -> Just BB
+    "HB" -> Just HB
+    "HH" -> Just HH
+    "HE" -> Just HE
+    "MV" -> Just MV
+    "NI" -> Just NI
+    "NW" -> Just NW
+    "RP" -> Just RP
+    "SL" -> Just SL
+    "SN" -> Just SN
+    "ST" -> Just ST
+    "SH" -> Just SH
+    "TH" -> Just TH
+    _ -> Nothing
+
+holidays :: S.Set GermanRegion -> ([Year -> Holiday], [DateTransform])
 holidays regions =
   ( concat
       [ federalHolidays,
@@ -35,27 +90,26 @@
     hday "second_day_of_christmas" . boxingDay
   ]
 
-regionalHolidays :: [Region] -> [Year -> Holiday]
+regionalHolidays :: S.Set GermanRegion -> [Year -> Holiday]
 regionalHolidays =
   concatMap
     ( \r -> case r of
-        "BW" -> badenWurttembergHolidays
-        "BY" -> bavariaHolidays
-        "BE" -> berlinHolidays
-        "BB" -> brandenburgHolidays
-        "HB" -> bremenHolidays
-        "HH" -> hamburgHolidays
-        "HE" -> hesseHolidays
-        "MV" -> mecklenburgVorpommernHolidays
-        "NI" -> lowerSaxonyHolidays
-        "NW" -> northRhineWestphaliaHolidays
-        "RP" -> rhinelandPalatinateHolidays
-        "SL" -> saarlandHolidays
-        "SN" -> saxonyHolidays
-        "ST" -> saxonyAnhaltHolidays
-        "SH" -> schleswigHolsteinHolidays
-        "TH" -> thuringiaHolidays
-        _ -> []
+        BW -> badenWurttembergHolidays
+        BY -> bavariaHolidays
+        BE -> berlinHolidays
+        BB -> brandenburgHolidays
+        HB -> bremenHolidays
+        HH -> hamburgHolidays
+        HE -> hesseHolidays
+        MV -> mecklenburgVorpommernHolidays
+        NI -> lowerSaxonyHolidays
+        NW -> northRhineWestphaliaHolidays
+        RP -> rhinelandPalatinateHolidays
+        SL -> saarlandHolidays
+        SN -> saxonyHolidays
+        ST -> saxonyAnhaltHolidays
+        SH -> schleswigHolsteinHolidays
+        TH -> thuringiaHolidays
     )
 
 -- common holidays
diff --git a/tst/Test/Holidays.hs b/tst/Test/Holidays.hs
--- a/tst/Test/Holidays.hs
+++ b/tst/Test/Holidays.hs
@@ -12,8 +12,8 @@
 day :: Year -> MonthOfYear -> DayOfMonth -> Day
 day = fromGregorian
 
-countryPropTests :: H.ISO_3166_1_Alpha_3 -> [H.Region] -> TestTree
-countryPropTests countryCode regions =
+countryPropTests :: H.ISO_3166_1_Alpha_3 -> TestTree
+countryPropTests countryCode =
   let uniqueYears c y =
         S.map
           ( \h ->
@@ -22,7 +22,7 @@
               in
                 year'
           )
-          (H.holidays c regions y)
+          (H.holidays c y)
   in  testGroup
         ("Holidays property based tests for country " <> show countryCode)
         [ QC.testProperty "Day always in the same year" $
diff --git a/tst/Test/Holidays/Germany.hs b/tst/Test/Holidays/Germany.hs
--- a/tst/Test/Holidays/Germany.hs
+++ b/tst/Test/Holidays/Germany.hs
@@ -11,15 +11,15 @@
 import Test.Tasty.HUnit
 
 -- german states
-regions :: [Region]
-regions = ["BW", "BY", "BE", "BB", "HB", "HH", "HE", "MV", "NI", "NW", "RP", "SL", "SN", "ST", "SH", "TH"]
+regions :: S.Set GermanRegion
+regions = S.fromList [BW, BY, BE, BB, HB, HH, HE, MV, NI, NW, RP, SL, SN, ST, SH, TH]
 
 unitTests :: TestTree
 unitTests =
   testGroup
     "DEU unit tests"
     [ testCase "2025" $
-        sortOn holidayValue (S.toAscList (holidays "DEU" regions 2025))
+        sortOn holidayValue (S.toAscList (holidays (DEU regions) 2025))
           @?= [ hday "new_years_day" (day 2025 1 1),
                 hday "epiphany" (day 2025 1 6),
                 hday "international_womens_day" (day 2025 3 8),
@@ -44,4 +44,4 @@
     ]
 
 propTests :: TestTree
-propTests = countryPropTests "DEU" regions
+propTests = countryPropTests (DEU regions)
diff --git a/tst/Test/Holidays/Israel.hs b/tst/Test/Holidays/Israel.hs
--- a/tst/Test/Holidays/Israel.hs
+++ b/tst/Test/Holidays/Israel.hs
@@ -20,7 +20,7 @@
   testGroup
     "ISR unit tests"
     [ testCase "2024" $
-        sortOn holidayValue (excludeSabbaths (S.toAscList (holidays "ISR" [] 2024)))
+        sortOn holidayValue (excludeSabbaths (S.toAscList (holidays ISR 2024)))
           @?= [ hday "passover" (day 2024 4 23),
                 hday "seventh_day_of_passover" (day 2024 4 29),
                 hday "independence_day" (day 2024 5 13),
@@ -35,7 +35,7 @@
     ]
 
 propTests :: TestTree
-propTests = countryPropTests "ISR" []
+propTests = countryPropTests ISR
 
 excludeSabbaths :: [Holiday] -> [Holiday]
 excludeSabbaths hs = filter (not . T.isPrefixOf "sabbath_" . holidayKey) hs
diff --git a/tst/Test/Holidays/Mozambique.hs b/tst/Test/Holidays/Mozambique.hs
--- a/tst/Test/Holidays/Mozambique.hs
+++ b/tst/Test/Holidays/Mozambique.hs
@@ -15,7 +15,7 @@
   testGroup
     "MOZ unit tests"
     [ testCase "2025" $
-        sortOn holidayValue (S.toList (holidays "MOZ" [] 2025))
+        sortOn holidayValue (S.toList (holidays MOZ 2025))
           @?= [ hday "new_years_day" (day 2025 1 1),
                 hday "heroes_day" (day 2025 2 3),
                 hday "womens_day" (day 2025 4 7),
@@ -29,15 +29,4 @@
     ]
 
 propTests :: TestTree
-propTests = countryPropTests "MOZ" []
-
-{-
- ( [ hday "new_years_day" . newYearsDay,
-      hday "heroes_day" . feb 3,
-      hday "womens_day" . apr 7,
-      hday "workers_day" . workersDay,
-      hday "independence_day" . jun 25,
-      hday "victory_day" . sep 7,
-      hday "armed_forces_day" . sep 25,
-      hday "day_of_peace_and_reconciliation" . oct 4,
-      hday "family_day" . christmasDay -}
+propTests = countryPropTests MOZ
diff --git a/tst/Test/Holidays/Namibia.hs b/tst/Test/Holidays/Namibia.hs
--- a/tst/Test/Holidays/Namibia.hs
+++ b/tst/Test/Holidays/Namibia.hs
@@ -15,7 +15,7 @@
   testGroup
     "NAM unit tests"
     [ testCase "2024" $
-        sortOn holidayValue (S.toAscList (holidays "NAM" [] 2024))
+        sortOn holidayValue (S.toAscList (holidays NAM 2024))
           @?= [ hday "new_years_day" (day 2024 1 1),
                 hday "independence_day" (day 2024 3 21),
                 hday "good_friday" (day 2024 3 29),
@@ -30,7 +30,7 @@
                 hday "family_day" (day 2024 12 26)
               ],
       testCase "2025" $
-        sortOn holidayValue (S.toAscList (holidays "NAM" [] 2025))
+        sortOn holidayValue (S.toAscList (holidays NAM 2025))
           @?= [ hday "new_years_day" (day 2025 1 1),
                 hday "independence_day" (day 2025 3 21),
                 hday "good_friday" (day 2025 4 18),
@@ -48,4 +48,4 @@
     ]
 
 propTests :: TestTree
-propTests = countryPropTests "NAM" []
+propTests = countryPropTests NAM
diff --git a/tst/Test/Holidays/SouthAfrica.hs b/tst/Test/Holidays/SouthAfrica.hs
--- a/tst/Test/Holidays/SouthAfrica.hs
+++ b/tst/Test/Holidays/SouthAfrica.hs
@@ -15,7 +15,7 @@
   testGroup
     "ZAF unit tests"
     [ testCase "2024" $
-        sortOn holidayValue (S.toAscList (holidays "ZAF" [] 2024))
+        sortOn holidayValue (S.toAscList (holidays ZAF 2024))
           @?= [ hday "new_years_day" (day 2024 1 1),
                 hday "human_rights_day" (day 2024 3 21),
                 hday "good_friday" (day 2024 3 29),
@@ -31,7 +31,7 @@
                 hday "day_of_goodwill" (day 2024 12 26)
               ],
       testCase "2025" $
-        sortOn holidayValue (S.toList (holidays "ZAF" [] 2025))
+        sortOn holidayValue (S.toList (holidays ZAF 2025))
           @?= [ hday "new_years_day" (day 2025 1 1),
                 hday "human_rights_day" (day 2025 3 21),
                 hday "good_friday" (day 2025 4 18),
@@ -48,4 +48,4 @@
     ]
 
 propTests :: TestTree
-propTests = countryPropTests "ZAF" []
+propTests = countryPropTests ZAF
diff --git a/tst/Test/Holidays/UnitedKingdom.hs b/tst/Test/Holidays/UnitedKingdom.hs
--- a/tst/Test/Holidays/UnitedKingdom.hs
+++ b/tst/Test/Holidays/UnitedKingdom.hs
@@ -15,7 +15,7 @@
   testGroup
     "GBR unit tests"
     [ testCase "2025" $
-        sortOn holidayValue (S.toList (holidays "GBR" [] 2025))
+        sortOn holidayValue (S.toList (holidays GBR 2025))
           @?= [ hday "new_years_day" (day 2025 1 1),
                 hday "good_friday" (day 2025 4 18),
                 hday "easter_sunday" (day 2025 4 21),
@@ -26,7 +26,7 @@
                 hday "boxing_day" (day 2025 12 26)
               ],
       testCase "2026" $
-        sortOn holidayValue (S.toList (holidays "GBR" [] 2026))
+        sortOn holidayValue (S.toList (holidays GBR 2026))
           @?= [ hday "new_years_day" (day 2026 1 1),
                 hday "good_friday" (day 2026 4 3),
                 hday "easter_sunday" (day 2026 4 6),
@@ -39,4 +39,4 @@
     ]
 
 propTests :: TestTree
-propTests = countryPropTests "GBR" []
+propTests = countryPropTests GBR
diff --git a/tst/Test/Holidays/UnitedStates.hs b/tst/Test/Holidays/UnitedStates.hs
--- a/tst/Test/Holidays/UnitedStates.hs
+++ b/tst/Test/Holidays/UnitedStates.hs
@@ -15,7 +15,7 @@
   testGroup
     "USA unit tests"
     [ testCase "2025" $
-        sortOn holidayValue (S.toAscList (holidays "USA" [] 2025))
+        sortOn holidayValue (S.toAscList (holidays USA 2025))
           @?= [ hday "new_years_day" (day 2025 1 1),
                 hday "martin_luther_kings_birthday" (day 2025 1 20),
                 hday "george_washingtons_birthday" (day 2025 2 17),
@@ -31,4 +31,4 @@
     ]
 
 propTests :: TestTree
-propTests = countryPropTests "USA" []
+propTests = countryPropTests USA
