diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright © 2009—2011 Roel van Dijk, Bas van Dijk
+Copyright 2009—2014 Roel van Dijk, Bas van Dijk
 
 All rights reserved.
 
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -1,38 +1,74 @@
 Numerals
 ========
 
-Convert numbers to number words in a number of languages. Each
-language has its own module. The module name is based on one of the
-ISO 639 Alpha codes. Each module contains one or more `cardinal`
-functions and a `struct` function. The `cardinal` functions directly
-convert cardinal numbers to a string-like representation of their
-spoken form. The `struct` functions convert numbers to a polymorphic
-representation of their grammatical structure. All language modules
-are implemented using the @numerals-base@ package.
+Convert numbers to numerals (number words) in a number of
+languages. Each language has its own module. The module name is based
+on one of the ISO 639 Alpha codes. Each module contains one or more
+functions to convert numerical values to numerals. Several types of
+numerals are supported. But not every type is supported by every
+language. Some because they do not occur in that language. Others
+because they are not yet defined in this package.
 
-The use of this package is best understood with some examples. Because
-the results of conversion are polymorphic we need to choose a specific
-type. For these examples we'll use simple strings. But any type that
-has instances for `Monoid` and `IsString` will work. First some
-English number names, both British and US variants:
+- Cardinal numerals
 
+  Describe quantity - _one_, _two_, _three_, etc.
+
+- Ordinal numerals
+
+  Describe position in a sequential order - _first_, _second_,
+  _third_, etc.
+
+- Partitive numerals
+
+  Describe division into fractions - _two thirds_, _three quarters_.
+
+- Multiplicative numerals
+
+  Describe repetition, how many time - _once_, _twice_, _thrice_.
+
+### Inflection
+
+In some languages number words are modified based on a number of
+grammatical categories such as _gender_ or _number_. For instance, in
+Spanish, the numeral for the quantity '1' can be one of _uno_, _un_ or
+_una_ depending on whether it is of the neuter, masculine or feminine
+gender. In order to support this process every conversion function
+takes an inflection parameter which defines the grammatical state.
+
+Inflections are not concrete types, but polymorphic parameters
+constrained by type classes. Use the reified inflection type provided
+by the `numerals-base` package to get a concrete value:
+
+    >>> import Text.Numeral.Grammar.Reified ( defaultInflection )
+
+### Numeral structure
+
+The `struct` functions convert numbers to a polymorphic representation
+of their grammatical structure. They are found in every language
+module.
+
+### Examples
+
+The use of this package is best understood with some examples. First
+some English number names, both British and US variants:
+
     >>> import qualified Text.Numeral.Language.EN as EN
-    >>> EN.uk_cardinal 123 :: Maybe String
+    >>> EN.uk_cardinal defaultInflection 123 :: Maybe Text
     Just "one hundred and twenty-three"
-    >>> EN.us_cardinal (10^50 + 42) :: Maybe String
+    >>> EN.us_cardinal defaultInflection (10^50 + 42) :: Maybe Text
     Just "one hundred quindecillion forty-two"
 
 French, which contains some traces of a base 20 system:
 
     >>> import qualified Text.Numeral.Language.FR as FR
-    >>> FR.cardinal (-99) :: Maybe String
+    >>> FR.cardinal defaultInflection (-99) :: Maybe Text
     Just "moins quatre-vingt-dix-neuf"
 
 Conversions can fail. Alamblak, a language spoken by a few people in
 Papua New Guinea, has no representation for negative numbers:
 
     >>> import qualified Text.Numeral.Language.AMP as AMP
-    >>> AMP.cardinal (-3) :: Maybe String
+    >>> AMP.cardinal defaultInflection (-3) :: Maybe Text
     Nothing
 
 Some languages have multiple scripts and methods for writing number
@@ -42,33 +78,46 @@
 Traditional Chinese characters:
 
     >>> import qualified Text.Numeral.Language.ZH as ZH
-    >>> ZH.trad_cardinal 123456 :: Maybe String
+    >>> ZH.trad_cardinal defaultInflection 123456 :: Maybe Text
     Just "十二萬三千四百五十六"
 
 Simplified characters for use in financial contexts:
 
-    >>> ZH.finance_simpl_cardinal 123456 :: Maybe String
+    >>> ZH.finance_simpl_cardinal defaultInflection 123456 :: Maybe Text
     Just "拾贰万参仟肆伯伍拾陆"
 
 Transcribed using Pinyin:
 
-    >>> ZH.pinyin_cardinal 123456 :: Maybe String
+    >>> ZH.pinyin_cardinal defaultInflection 123456 :: Maybe Text
     Just "shíèrwàn sānqiān sìbǎi wǔshí liù"
 
+In Spanish the word for the quantity '1' differs based on its
+gender. We convey the gender via the inflection parameter:
+
+    >>> import Text.Numeral.Grammar ( masculine, feminine, neuter )
+    >>> import Text.Numeral.Grammar.Reified ( defaultInflection )
+    >>> import qualified Text.Numeral.Language.ES as ES
+    >>> ES.cardinal (masculine defaultInflection) 1 :: Maybe Text
+    Just "un"
+    >>> ES.cardinal (feminine defaultInflection) 1 :: Maybe Text
+    Just "una"
+    >>> ES.cardinal (neuter defaultInflection) 1 :: Maybe Text
+    Just "uno"
+
 Using the `struct` functions you can see the grammatical structure of
 number names. Because the results of these functions are polymorphic
 you need to specify a specific type.
 
     >>> import qualified Text.Numeral.Language.NL as NL
-    >>> NL.struct 123 :: Maybe Integer
-    Just 123
-    >>> import Text.Numeral
-    >>> NL.struct 123 :: Maybe Exp
-    Just (Add (Lit 100) (Add (Lit 3) (Mul (Lit 2) (Lit 10))))
+    >>> NL.struct 123 :: Integer
+    123
+    >>> import Text.Numeral.Exp.Reified ( Exp, showExp )
+    >>> showExp (NL.struct 123 :: Exp i)
+    Add (Lit 100) (Add (Lit 3) (Mul (Lit 2) (Lit 10)))
 
 Compare with:
 
-    >>> NL.cardinal 123 :: Maybe String
+    >>> NL.cardinal defaultInflection 123 :: Maybe Text
     Just "honderddrieëntwintig"
 
 100 (honderd) + (3 (drie) + (ën) 2 (twin) * 10 (tig))
diff --git a/numerals.cabal b/numerals.cabal
--- a/numerals.cabal
+++ b/numerals.cabal
@@ -1,51 +1,47 @@
 name:          numerals
-version:       0.3.0.1
+version:       0.4
 cabal-version: >= 1.8
 build-type:    Simple
 stability:     experimental
 author:        Roel van Dijk <vandijk.roel@gmail.com>, Bas van Dijk <v.dijk.bas@gmail.com>
 maintainer:    Roel van Dijk <vandijk.roel@gmail.com>
-copyright:     2009–2011 Roel van Dijk, Bas van Dijk
+copyright:     2009–2014 Roel van Dijk, Bas van Dijk
 license:       BSD3
 license-file:  LICENSE
 homepage:      https://github.com/roelvandijk/numerals
 bug-reports:   https://github.com/roelvandijk/numerals/issues
 category:      Natural Language Processing, Numerical, Text
 synopsis:      Convert numbers to number words
-description:   
+description:
   Convert numbers to number words in a number of languages. Each
   language has its own module. The module name is based on one of the
-  ISO 639 Alpha codes. Each module contains one or more 'cardinal'
-  functions and a 'struct' function. The 'cardinal' functions directly
-  convert cardinal numbers to a string-like representation of their
-  spoken form. The 'struct' functions convert numbers to a polymorphic
-  representation of their grammatical structure. All language modules
-  are implemented using the @numerals-base@ package.
+  ISO 639 Alpha codes. Each module contains one or more 'cardinal' and
+  'ordinal' functions and a 'struct' function. The 'cardinal'
+  functions directly convert cardinal numbers to a string-like
+  representation of their spoken form. The 'ordinal' functions do the
+  same but for ordinal numbers. The 'struct' functions convert numbers
+  to a polymorphic representation of their grammatical structure.
   .
-  The use of this package is best understood with some
-  examples. Because the results of conversion are polymorphic we need
-  to choose a specific type. For these examples we'll use simple
-  strings. But any type that has instances for 'Monoid' and 'IsString'
-  will work. First some English number names, both British and US
-  variants:
+  The use of this package is best understood with some examples. First
+  some English number names, both British and US variants:
   .
   >>> import qualified Text.Numeral.Language.EN as EN
-  >>> EN.uk_cardinal 123 :: Maybe String
+  >>> EN.uk_cardinal defaultInflection 123 :: Maybe Text
   Just "one hundred and twenty-three"
-  >>> EN.us_cardinal (10^50 + 42) :: Maybe String
+  >>> EN.us_cardinal defaultInflection (10^50 + 42) :: Maybe Text
   Just "one hundred quindecillion forty-two"
   .
   French, which contains some traces of a base 20 system:
   .
   >>> import qualified Text.Numeral.Language.FR as FR
-  >>> FR.cardinal (-99) :: Maybe String
+  >>> FR.cardinal defaultInflection (-99) :: Maybe Text
   Just "moins quatre-vingt-dix-neuf"
   .
   Conversions can fail. Alamblak, a language spoken by a few people in
   Papua New Guinea, has no representation for negative numbers:
   .
   >>> import qualified Text.Numeral.Language.AMP as AMP
-  >>> AMP.cardinal (-3) :: Maybe String
+  >>> AMP.cardinal defaultInflection (-3) :: Maybe Text
   Nothing
   .
   Some languages have multiple scripts and methods for writing number
@@ -55,17 +51,17 @@
   Traditional Chinese characters:
   .
   >>> import qualified Text.Numeral.Language.ZH as ZH
-  >>> ZH.trad_cardinal 123456 :: Maybe String
+  >>> ZH.trad_cardinal defaultInflection 123456 :: Maybe Text
   Just "十二萬三千四百五十六"
   .
   Simplified characters for use in financial contexts:
   .
-  >>> ZH.finance_simpl_cardinal 123456 :: Maybe String
+  >>> ZH.finance_simpl_cardinal defaultInflection 123456 :: Maybe Text
   Just "拾贰万参仟肆伯伍拾陆"
   .
   Transcribed using Pinyin:
   .
-  >>> ZH.pinyin_cardinal 123456 :: Maybe String
+  >>> ZH.pinyin_cardinal defaultInflection 123456 :: Maybe Text
   Just "shíèrwàn sānqiān sìbǎi wǔshí liù"
   .
   Using the 'struct' functions you can see the grammatical structure
@@ -73,15 +69,15 @@
   polymorphic you need to specify a specific type.
   .
   >>> import qualified Text.Numeral.Language.NL as NL
-  >>> NL.struct 123 :: Maybe Integer
-  Just 123
+  >>> NL.struct 123 :: Integer
+  123
   >>> import Text.Numeral
-  >>> NL.struct 123 :: Maybe Exp
-  Just (Add (Lit 100) (Add (Lit 3) (Mul (Lit 2) (Lit 10))))
+  >>> NL.struct 123 :: Exp
+  Add (Lit 100) (Add (Lit 3) (Mul (Lit 2) (Lit 10)))
   .
   Compare with:
   .
-  >>> NL.cardinal 123 :: Maybe String
+  >>> NL.cardinal defaultInflection 123 :: Maybe Text
   Just "honderddrieëntwintig"
   .
   100 (honderd) + (3 (drie) + (ën) 2 (twin) * 10 (tig))
@@ -100,29 +96,57 @@
   hs-source-dirs: src
   ghc-options: -Wall
 
-  build-depends: base                       >= 3.0.3.1 && < 4.5
-               , base-unicode-symbols       >= 0.1.1   && < 0.3
-               , containers                 >= 0.4     && < 0.5
+  build-depends: base                       >= 3.0.3.1 && < 4.7
+               , base-unicode-symbols       >= 0.2.2   && < 0.3
+               , containers                 >= 0.4     && < 0.6
                , containers-unicode-symbols >= 0.3     && < 0.4
-               , numerals-base              >= 0.3     && < 0.4
+               , fingertree                 >= 0.0.1   && < 0.2
+               , text                       >= 0.11    && < 1.2
 
-  exposed-modules: Text.Numeral.Language.AMP
+  if impl(ghc >= 7.2.1)
+    build-depends: integer-gmp >= 0.3 && < 0.6
+
+  exposed-modules: Text.Numeral
+                 , Text.Numeral.BigNum
+                 , Text.Numeral.Entry
+                 , Text.Numeral.Exp
+                 , Text.Numeral.Exp.Reified
+                 , Text.Numeral.Grammar
+                 , Text.Numeral.Grammar.Reified
+                 , Text.Numeral.Misc
+                 , Text.Numeral.Render
+                 , Text.Numeral.Rules
+
+                 , Text.Numeral.Language.Entries
+                 , Text.Numeral.Language.AF
+                 , Text.Numeral.Language.AMP
+                 , Text.Numeral.Language.BG
                  , Text.Numeral.Language.CHN
+                 , Text.Numeral.Language.CHR
+                 , Text.Numeral.Language.CLM
+                 , Text.Numeral.Language.CS
                  , Text.Numeral.Language.DE
                  , Text.Numeral.Language.EN
                  , Text.Numeral.Language.EO
                  , Text.Numeral.Language.ES
+                 , Text.Numeral.Language.FI
                  , Text.Numeral.Language.FR
+                 , Text.Numeral.Language.FUR
+                 , Text.Numeral.Language.GSW
                  , Text.Numeral.Language.GV
+                 , Text.Numeral.Language.HE
+                 , Text.Numeral.Language.HOP
                  , Text.Numeral.Language.IT
                  , Text.Numeral.Language.JA
                  , Text.Numeral.Language.LA
+                 , Text.Numeral.Language.LLD
                  , Text.Numeral.Language.MG
                  , Text.Numeral.Language.NL
                  , Text.Numeral.Language.NO
                  , Text.Numeral.Language.NQM
                  , Text.Numeral.Language.OJ
-              -- , Text.Numeral.Language.PAA
+                 , Text.Numeral.Language.PDC
+                 , Text.Numeral.Language.PL
                  , Text.Numeral.Language.PT
                  , Text.Numeral.Language.RU
                  , Text.Numeral.Language.SCO
@@ -131,47 +155,99 @@
                  , Text.Numeral.Language.WO
                  , Text.Numeral.Language.YOR
                  , Text.Numeral.Language.ZH
+  other-modules: Text.Numeral.Render.Utils
 
+
 -------------------------------------------------------------------------------
 
 test-suite test-numerals
   type: exitcode-stdio-1.0
   main-is: test.hs
-  hs-source-dirs: src, test
+  hs-source-dirs: src-test
 
-  other-modules: Text.Numeral.Language.CHN.TestData
+  other-modules: Text.Numeral.Test
+
+               , Text.Numeral.Language.ACH.TestData
+               , Text.Numeral.Language.ADY.TestData
+               , Text.Numeral.Language.AF.TestData
                , Text.Numeral.Language.AMP.TestData
+               , Text.Numeral.Language.ARI.TestData
+               , Text.Numeral.Language.AST.TestData
+               , Text.Numeral.Language.AZ.TestData
+               , Text.Numeral.Language.BA.TestData
+               , Text.Numeral.Language.BG.TestData
+               , Text.Numeral.Language.BM.TestData
+               , Text.Numeral.Language.CA.TestData
+               , Text.Numeral.Language.CAF.TestData
+               , Text.Numeral.Language.CBK.TestData
+               , Text.Numeral.Language.CHN.TestData
+               , Text.Numeral.Language.CHR.TestData
+               , Text.Numeral.Language.CLM.TestData
+               , Text.Numeral.Language.CO.TestData
+               , Text.Numeral.Language.COD.TestData
+               , Text.Numeral.Language.COO.TestData
+               , Text.Numeral.Language.CS.TestData
+               , Text.Numeral.Language.CY.TestData
                , Text.Numeral.Language.DE.TestData
+               , Text.Numeral.Language.DJK.TestData
                , Text.Numeral.Language.EN.TestData
                , Text.Numeral.Language.EO.TestData
                , Text.Numeral.Language.ES.TestData
+               , Text.Numeral.Language.ET.TestData
+               , Text.Numeral.Language.FI.TestData
+               , Text.Numeral.Language.FO.TestData
                , Text.Numeral.Language.FR.TestData
+               , Text.Numeral.Language.FUR.TestData
+               , Text.Numeral.Language.GCF_MTQ.TestData
+               , Text.Numeral.Language.GIL.TestData
+               , Text.Numeral.Language.GL.TestData
+               , Text.Numeral.Language.GSW.TestData
                , Text.Numeral.Language.GV.TestData
+               , Text.Numeral.Language.HAI.TestData
+               , Text.Numeral.Language.HE.TestData
+               , Text.Numeral.Language.HOP.TestData
+               , Text.Numeral.Language.HR.TestData
+               , Text.Numeral.Language.HU.TestData
+               , Text.Numeral.Language.HY.TestData
                , Text.Numeral.Language.IT.TestData
                , Text.Numeral.Language.JA.TestData
+               , Text.Numeral.Language.KAP.TestData
+               , Text.Numeral.Language.KEA.TestData
                , Text.Numeral.Language.LA.TestData
+               , Text.Numeral.Language.LLD.TestData
                , Text.Numeral.Language.MG.TestData
+               , Text.Numeral.Language.MOH.TestData
                , Text.Numeral.Language.NL.TestData
                , Text.Numeral.Language.NO.TestData
                , Text.Numeral.Language.NQM.TestData
                , Text.Numeral.Language.OJ.TestData
-            -- , Text.Numeral.Language.PAA.TestData
+               , Text.Numeral.Language.PAA.TestData
+               , Text.Numeral.Language.PDC.TestData
+               , Text.Numeral.Language.PL.TestData
                , Text.Numeral.Language.PT.TestData
+               , Text.Numeral.Language.RMN_DZA.TestData
+               , Text.Numeral.Language.RO.TestData
                , Text.Numeral.Language.RU.TestData
                , Text.Numeral.Language.SCO.TestData
                , Text.Numeral.Language.SV.TestData
+               , Text.Numeral.Language.TAR.TestData
                , Text.Numeral.Language.TR.TestData
                , Text.Numeral.Language.WO.TestData
                , Text.Numeral.Language.YOR.TestData
+               , Text.Numeral.Language.ZAQ.TestData
                , Text.Numeral.Language.ZH.TestData
-  ghc-options: -Wall
+               , Text.Numeral.Language.ZPC.TestData
+  ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
 
-  build-depends: base                       >= 3.0.3.1 && < 4.4
-               , base-unicode-symbols       >= 0.1.1   && < 0.3
-               , containers                 >= 0.4     && < 0.5
-               , containers-unicode-symbols >= 0.3     && < 0.4
-               , numerals-base              >= 0.3     && < 0.4
+  build-depends: base                       >= 3.0.3.1 && < 4.7
+               , base-unicode-symbols       >= 0.2.2   && < 0.3
                , HUnit                      >= 1.2.2   && < 1.3
-               , test-framework             >= 0.3.3   && < 0.5
-               , test-framework-hunit       >= 0.2.6   && < 0.3
+               , QuickCheck                 >= 2.4.2   && < 2.7
+               , test-framework             >= 0.3.3   && < 0.9
+               , test-framework-hunit       >= 0.2.6   && < 0.4
+               , test-framework-quickcheck2 >= 0.2.12  && < 0.4
+               , text                       >= 0.11    && < 1.2
+               , numerals
 
+  if impl(ghc >= 7.2.1)
+    build-depends: integer-gmp >= 0.3 && < 0.6
diff --git a/src-test/Text/Numeral/Language/ACH/TestData.hs b/src-test/Text/Numeral/Language/ACH/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/ACH/TestData.hs
@@ -0,0 +1,191 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        ach
+
+[@ISO639-3@]        ach
+
+[@Native name@]     Lwo
+
+[@English name@]    Acholi
+-}
+module Text.Numeral.Language.ACH.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-acholi/en/ach/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "acel")
+      , (2, "aryo")
+      , (3, "adek")
+      , (4, "aŋwen")
+      , (5, "abic")
+      , (6, "abicel")
+      , (7, "abiro")
+      , (8, "aboro")
+      , (9, "aboŋwen")
+      , (10, "apar")
+      , (11, "apar wiye acel")
+      , (12, "apar wiye aryo")
+      , (13, "apar wiye adek")
+      , (14, "apar wiye aŋwen")
+      , (15, "apar wiye abic")
+      , (16, "apar wiye abicel")
+      , (17, "apar wiye abiro")
+      , (18, "apar wiye aboro")
+      , (19, "apar wiye aboŋwen")
+      , (20, "pyeraryo")
+      , (21, "pyeraryo wiye acel")
+      , (22, "pyeraryo wiye aryo")
+      , (23, "pyeraryo wiye adek")
+      , (24, "pyeraryo wiye aŋwen")
+      , (25, "pyeraryo wiye abic")
+      , (26, "pyeraryo wiye abicel")
+      , (27, "pyeraryo wiye abiro")
+      , (28, "pyeraryo wiye aboro")
+      , (29, "pyeraryo wiye aboŋwen")
+      , (30, "pyeradek")
+      , (31, "pyeradek wiye acel")
+      , (32, "pyeradek wiye aryo")
+      , (33, "pyeradek wiye adek")
+      , (34, "pyeradek wiye aŋwen")
+      , (35, "pyeradek wiye abic")
+      , (36, "pyeradek wiye abicel")
+      , (37, "pyeradek wiye abiro")
+      , (38, "pyeradek wiye aboro")
+      , (39, "pyeradek wiye aboŋwen")
+      , (40, "pyeraŋwen")
+      , (41, "pyeraŋwen wiye acel")
+      , (42, "pyeraŋwen wiye aryo")
+      , (43, "pyeraŋwen wiye adek")
+      , (44, "pyeraŋwen wiye aŋwen")
+      , (45, "pyeraŋwen wiye abic")
+      , (46, "pyeraŋwen wiye abicel")
+      , (47, "pyeraŋwen wiye abiro")
+      , (48, "pyeraŋwen wiye aboro")
+      , (49, "pyeraŋwen wiye aboŋwen")
+      , (50, "pyerabic")
+      , (51, "pyerabic wiye acel")
+      , (52, "pyerabic wiye aryo")
+      , (53, "pyerabic wiye adek")
+      , (54, "pyerabic wiye aŋwen")
+      , (55, "pyerabic wiye abic")
+      , (56, "pyerabic wiye abicel")
+      , (57, "pyerabic wiye abiro")
+      , (58, "pyerabic wiye aboro")
+      , (59, "pyerabic wiye aboŋwen")
+      , (60, "pyerabicel")
+      , (61, "pyerabicel wiye acel")
+      , (62, "pyerabicel wiye aryo")
+      , (63, "pyerabicel wiye adek")
+      , (64, "pyerabicel wiye aŋwen")
+      , (65, "pyerabicel wiye abic")
+      , (66, "pyerabicel wiye abicel")
+      , (67, "pyerabicel wiye abiro")
+      , (68, "pyerabicel wiye aboro")
+      , (69, "pyerabicel wiye aboŋwen")
+      , (70, "pyerabiro")
+      , (71, "pyerabiro wiye acel")
+      , (72, "pyerabiro wiye aryo")
+      , (73, "pyerabiro wiye adek")
+      , (74, "pyerabiro wiye aŋwen")
+      , (75, "pyerabiro wiye abic")
+      , (76, "pyerabiro wiye abicel")
+      , (77, "pyerabiro wiye abiro")
+      , (78, "pyerabiro wiye aboro")
+      , (79, "pyerabiro wiye aboŋwen")
+      , (80, "pyeraboro")
+      , (81, "pyeraboro wiye acel")
+      , (82, "pyeraboro wiye aryo")
+      , (83, "pyeraboro wiye adek")
+      , (84, "pyeraboro wiye aŋwen")
+      , (85, "pyeraboro wiye abic")
+      , (86, "pyeraboro wiye abicel")
+      , (87, "pyeraboro wiye abiro")
+      , (88, "pyeraboro wiye aboro")
+      , (89, "pyeraboro wiye aboŋwen")
+      , (90, "pyeraboŋwen")
+      , (91, "pyeraboŋwen wiye acel")
+      , (92, "pyeraboŋwen wiye aryo")
+      , (93, "pyeraboŋwen wiye adek")
+      , (94, "pyeraboŋwen wiye aŋwen")
+      , (95, "pyeraboŋwen wiye abic")
+      , (96, "pyeraboŋwen wiye abicel")
+      , (97, "pyeraboŋwen wiye abiro")
+      , (98, "pyeraboŋwen wiye aboro")
+      , (99, "pyeraboŋwen wiye aboŋwen")
+      , (100, "miya")
+      , (101, "miya acel ki acel")
+      , (102, "miya acel ki aryo")
+      , (103, "miya acel ki adek")
+      , (104, "miya acel ki aŋwen")
+      , (105, "miya acel ki abic")
+      , (106, "miya acel ki abicel")
+      , (107, "miya acel ki abiro")
+      , (108, "miya acel ki aboro")
+      , (109, "miya acel ki aboŋwen")
+      , (110, "miya acel ki apar")
+      , (123, "miya acel ki pyeraryo wiye adek")
+      , (200, "miya aryo")
+      , (300, "miya adek")
+      , (321, "miya adek ki pyeraryo wiye acel")
+      , (400, "miya aŋwen")
+      , (500, "miya abic")
+      , (600, "miya abicel")
+      , (700, "miya abiro")
+      , (800, "miya aboro")
+      , (900, "miya aboŋwen")
+      , (909, "miya aboŋwen ki aboŋwen")
+      , (990, "miya aboŋwen ki pyeraboŋwen")
+      , (999, "miya aboŋwen ki pyeraboŋwen wiye aboŋwen")
+      , (1000, "elfu")
+      , (1001, "elfu acel ki acel")
+      , (1008, "elfu acel ki aboro")
+      , (1234, "elfu acel ki miya aryo ki pyeradek wiye aŋwen")
+      , (2000, "elfu aryo")
+      , (3000, "elfu adek")
+      , (4000, "elfu aŋwen")
+      , (4321, "elfu aŋwen ki miya adek ki pyeraryo wiye acel")
+      , (5000, "elfu abic")
+      , (6000, "elfu abicel")
+      , (7000, "elfu abiro")
+      , (8000, "elfu aboro")
+      , (9000, "elfu aboŋwen")
+      , (10000, "elfu apar")
+      , (12345, "apar wiye aryo elfu miya adek ki pyeraŋwen wiye abic")
+      , (20000, "elfu pyeraryo")
+      , (30000, "elfu pyeradek")
+      , (40000, "elfu pyeraŋwen")
+      , (50000, "elfu pyerabic")
+      , (54321, "elfu pyerabic wiye aŋwen ki miya adek ki pyeraryo wiye acel")
+      , (60000, "elfu pyerabicel")
+      , (70000, "elfu pyerabiro")
+      , (80000, "elfu pyeraboro")
+      , (90000, "elfu pyeraboŋwen")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/ADY/TestData.hs b/src-test/Text/Numeral/Language/ADY/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/ADY/TestData.hs
@@ -0,0 +1,181 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        ady
+
+[@ISO639-3@]        ady
+
+[@Native name@]     Адыгэбзэ
+
+[@English name@]    Adyghe
+-}
+module Text.Numeral.Language.ADY.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-adyghe/en/ady/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "зиI")
+      , (1, "зы")
+      , (2, "тIу")
+      , (3, "щы")
+      , (4, "плIы")
+      , (5, "тфы")
+      , (6, "хы")
+      , (7, "блы")
+      , (8, "и")
+      , (9, "бгъу")
+      , (10, "пшIы")
+      , (11, "пшIыкIузы")
+      , (12, "пшIыкIутIу")
+      , (13, "пшIыкIущы")
+      , (14, "пшIыкIуплIы")
+      , (15, "пшIыкIутфы")
+      , (16, "пшIыкIухы")
+      , (17, "пшIыкIублы")
+      , (18, "пшIыкIуи")
+      , (19, "пшIыкIубгъу")
+      , (20, "тоIкы")
+      , (21, "тIоIкырэ зырэ")
+      , (22, "тIоIкырэ тIурэ")
+      , (23, "тIоIкырэ щырэ")
+      , (24, "тIоIкырэ плIырэ")
+      , (25, "тIоIкырэ тфырэ")
+      , (26, "тIоIкырэ хырэ")
+      , (27, "тIоIкырэ блырэ")
+      , (28, "тIоIкырэ ирэ")
+      , (29, "тIоIкырэ бгъурэ")
+      , (30, "щэкIы")
+      , (31, "щэкIырэ зырэ")
+      , (32, "щэкIырэ тIурэ")
+      , (33, "щэкIырэ щырэ")
+      , (34, "щэкIырэ плIырэ")
+      , (35, "щэкIырэ тфырэ")
+      , (36, "щэкIырэ хырэ")
+      , (37, "щэкIырэ блырэ")
+      , (38, "щэкIырэ ирэ")
+      , (39, "щэкIырэ бгъурэ")
+      , (40, "тIокIитIу")
+      , (41, "тIокIитIурэ зырэ")
+      , (42, "тIокIитIурэ тIурэ")
+      , (43, "тIокIитIурэ щырэ")
+      , (44, "тIокIитIурэ плIырэ")
+      , (45, "тIокIитIурэ тфырэ")
+      , (46, "тIокIитIурэ хырэ")
+      , (47, "тIокIитIурэ блырэ")
+      , (48, "тIокIитIурэ ирэ")
+      , (49, "тIокIитIурэ бгъурэ")
+      , (50, "шъэнэкъо")
+      , (51, "шъэнкъэрэ зырэ")
+      , (52, "шъэнкъэрэ тIурэ")
+      , (53, "шъэнкъэрэ щырэ")
+      , (54, "шъэнкъэрэ плIырэ")
+      , (55, "шъэнкъэрэ тфырэ")
+      , (56, "шъэнкъэрэ хырэ")
+      , (57, "шъэнкъэрэ блырэ")
+      , (58, "шъэнкъэрэ ирэ")
+      , (59, "шъэнкъэрэ бгъурэ")
+      , (60, "токIищ")
+      , (61, "тIокIищырэ зырэ")
+      , (62, "тIокIищырэ тIурэ")
+      , (63, "тIокIищырэ щырэ")
+      , (64, "тIокIищырэ плIырэ")
+      , (65, "тIокIищырэ тфырэ")
+      , (66, "тIокIищырэ хырэ")
+      , (67, "тIокIищырэ блырэ")
+      , (68, "тIокIищырэ ирэ")
+      , (69, "тIокIищырэ бгъурэ")
+      , (70, "тIокIищырэ пшIырэ")
+      , (71, "тIокIищырэ пшIыкIузырэ")
+      , (72, "тIокIищырэ пшIыкIутIурэ")
+      , (73, "тIокIищырэ пшIыкIущырэ")
+      , (74, "тIокIищырэ пшIыкIуплIырэ")
+      , (75, "тIокIищырэ пшIыкIутфырэ")
+      , (76, "тIокIищырэ пшIыкIухырэ")
+      , (77, "тIокIищырэ пшIыкIублырэ")
+      , (78, "тIокIищырэ пшIыкIуирэ")
+      , (79, "тIокIищырэ пшIыкIубгъурэ")
+      , (80, "токIиплI")
+      , (81, "токIиплIырэ зырэ")
+      , (82, "токIиплIырэ тIурэ")
+      , (83, "токIиплIырэ щырэ")
+      , (84, "токIиплIырэ плIырэ")
+      , (85, "токIиплIырэ тфырэ")
+      , (86, "токIиплIырэ хырэ")
+      , (87, "токIиплIырэ блырэ")
+      , (88, "токIиплIырэ ирэ")
+      , (89, "токIиплIырэ бгъурэ")
+      , (90, "токIиплIырэ пшIырэ")
+      , (91, "токIиплIырэ пшIыкIузырэ")
+      , (92, "токIиплIырэ пшIыкIутIурэ")
+      , (93, "токIиплIырэ пшIыкIущырэ")
+      , (94, "токIиплIырэ пшIыкIуплIырэ")
+      , (95, "токIиплIырэ пшIыкIутфырэ")
+      , (96, "токIиплIырэ пшIыкIухырэ")
+      , (97, "токIиплIырэ пшIыкIублырэ")
+      , (98, "токIиплIырэ пшIыкIуирэ")
+      , (99, "токIиплIырэ пшIыкIубгъурэ")
+      , (100, "шъэ")
+      , (101, "шъэрэ зырэ")
+      , (102, "шъэрэ тIурэ")
+      , (103, "шъэрэ щырэ")
+      , (104, "шъэрэ плIырэ")
+      , (105, "шъэрэ тфырэ")
+      , (106, "шъэрэ хырэ")
+      , (107, "шъэрэ блырэ")
+      , (108, "шъэрэ ирэ")
+      , (109, "шъэрэ бгъурэ")
+      , (110, "шъэрэ пшIы")
+      , (123, "шъэрэ тIоIкырэ щырэ")
+      , (200, "шъитIу")
+      , (300, "шъищ")
+      , (321, "шъищ тIоIкырэ зырэ")
+      , (400, "шъиплI")
+      , (500, "шъитф")
+      , (600, "шъихы")
+      , (700, "шъиблы")
+      , (800, "шъии")
+      , (900, "шъибгъу")
+      , (909, "шъибгъу бгъу")
+      , (990, "шъибгъу токIиплIырэ пшIырэ")
+      , (999, "шъибгъу токIиплIырэ пшIыкIубгъурэ")
+      , (1000, "мин")
+      , (1001, "мин зырэ")
+      , (1008, "мин и")
+      , (1234, "мин шъитIурэ щэкIырэ плIырэ")
+      , (2000, "минитIу")
+      , (3000, "минищ")
+      , (4000, "миниплIы")
+      , (4321, "плIы миншъиищ тIоIкырэ зырэ")
+      , (5000, "минитфы")
+      , (6000, "минихы")
+      , (7000, "миниблы")
+      , (8000, "минии")
+      , (9000, "минибгъу")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/AF/TestData.hs b/src-test/Text/Numeral/Language/AF/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/AF/TestData.hs
@@ -0,0 +1,129 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        af
+
+[@ISO639-2@]        afr
+
+[@ISO639-3@]        afr
+
+[@Native name@]     Afrikaans
+
+[@English name@]    Afrikaans
+-}
+
+module Text.Numeral.Language.AF.TestData (cardinals, ordinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude       ( Integral )
+import "numerals" Text.Numeral.Misc ( dec )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-afrikaans/en/afr/
+  http://mylanguages.org/afrikaans_numbers.php
+-}
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "nul")
+      , (1, "een")
+      , (2, "twee")
+      , (3, "drie")
+      , (4, "vier")
+      , (5, "vyf")
+      , (6, "ses")
+      , (7, "sewe")
+      , (8, "ag")
+      , (9, "nege")
+      , (10, "tien")
+      , (11, "elf")
+      , (12, "twaalf")
+      , (13, "dertien")
+      , (14, "veertien")
+      , (15, "vyftien")
+      , (16, "sestien")
+      , (17, "sewentien")
+      , (18, "agtien")
+      , (19, "negentien")
+      , (20, "twintig")
+      , (21, "een-en-twintig")
+      , (22, "twee-en-twintig")
+      , (23, "drie-en-twintig")
+      , (24, "vier-en-twintig")
+      , (25, "vyf-en-twintig")
+      , (26, "ses-en-twintig")
+      , (27, "sewe-en-twintig")
+      , (28, "ag-en-twintig")
+      , (29, "nege-en-twintig")
+      , (30, "dertig")
+      , (31, "een-en-dertig")
+      , (32, "twee-en-dertig")
+      , (33, "drie-en-dertig")
+      , (34, "vier-en-dertig")
+      , (35, "vyf-en-dertig")
+      , (36, "ses-en-dertig")
+      , (37, "sewe-en-dertig")
+      , (38, "ag-en-dertig")
+      , (39, "nege-en-dertig")
+      , (40, "veertig")
+      , (50, "vyftig")
+      , (60, "sestig")
+      , (70, "sewentig")
+      , (80, "tagtig")
+      , (90, "neëntig")
+      , (100, "eenhonderd")
+      , (121, "eenhonderd een-en-twintig")
+      , (1000, "eenduisend")
+      , (1219, "eenduisend tweehonderd negentien")
+      , (dec 6, "een miljoen")
+      , (dec 9, "een miljard")
+      , (dec 12, "een biljoen")
+      ]
+    )
+  ]
+
+ordinals ∷ (Integral i) ⇒ TestData i
+ordinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "eerste")
+      , (2, "tweede")
+      , (3, "derde")
+      , (4, "vierde")
+      , (5, "vyfde")
+      , (6, "sesde")
+      , (7, "sewende")
+      , (8, "agtste")
+      , (9, "negende")
+      , (10, "tiende")
+      , (11, "elfde")
+      , (12, "twaalfde")
+      , (13, "dertiende")
+      , (14, "veertiende")
+      , (15, "vyftiende")
+      , (16, "sestiende")
+      , (17, "sewentiende")
+      , (18, "agtiende")
+      , (19, "negentiende")
+      , (20, "twintigste")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/AMP/TestData.hs b/src-test/Text/Numeral/Language/AMP/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/AMP/TestData.hs
@@ -0,0 +1,145 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        amp
+
+[@Native name@]     -
+
+[@English name@]    Alamblak
+-}
+
+module Text.Numeral.Language.AMP.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.sf.airnet.ne.jp/~ts/language/number/alamblak.html
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "rpat")
+      , (2, "hosf")
+      , (3, "hosfirpat")
+      , (4, "hosfihosf")
+      , (5, "tir yohtt")
+      , (6, "tir yohtti rpat")
+      , (7, "tir yohtti hosf")
+      , (8, "tir yohtti hosfirpat")
+      , (9, "tir yohtti hosfihosf")
+      , (10, "tir hosf")
+      , (11, "tir hosfi rpat")
+      , (12, "tir hosfi hosf")
+      , (13, "tir hosfi hosfirpat")
+      , (14, "tir hosfi hosfihosf")
+      , (15, "tir hosfirpat")
+      , (16, "tir hosfirpati rpat")
+      , (17, "tir hosfirpati hosf")
+      , (18, "tir hosfirpati hosfirpat")
+      , (19, "tir hosfirpati hosfihosf")
+      , (20, "yima yohtt")
+      , (21, "yima yohtti rpat")
+      , (22, "yima yohtti hosf")
+      , (23, "yima yohtti hosfirpat")
+      , (24, "yima yohtti hosfihosf")
+      , (25, "yima yohtti tir yohtt")
+      , (26, "yima yohtti tir yohtti rpat")
+      , (27, "yima yohtti tir yohtti hosf")
+      , (28, "yima yohtti tir yohtti hosfirpat")
+      , (29, "yima yohtti tir yohtti hosfihosf")
+      , (30, "yima yohtti tir hosf")
+      , (31, "yima yohtti tir hosfi rpat")
+      , (32, "yima yohtti tir hosfi hosf")
+      , (33, "yima yohtti tir hosfi hosfirpat")
+      , (34, "yima yohtti tir hosfi hosfihosf")
+      , (35, "yima yohtti tir hosfirpat")
+      , (36, "yima yohtti tir hosfirpati rpat")
+      , (37, "yima yohtti tir hosfirpati hosf")
+      , (38, "yima yohtti tir hosfirpati hosfirpat")
+      , (39, "yima yohtti tir hosfirpati hosfihosf")
+      , (40, "yima hosf")
+      , (41, "yima hosfi rpat")
+      , (42, "yima hosfi hosf")
+      , (43, "yima hosfi hosfirpat")
+      , (44, "yima hosfi hosfihosf")
+      , (45, "yima hosfi tir yohtt")
+      , (46, "yima hosfi tir yohtti rpat")
+      , (47, "yima hosfi tir yohtti hosf")
+      , (48, "yima hosfi tir yohtti hosfirpat")
+      , (49, "yima hosfi tir yohtti hosfihosf")
+      , (50, "yima hosfi tir hosf")
+      , (51, "yima hosfi tir hosfi rpat")
+      , (52, "yima hosfi tir hosfi hosf")
+      , (53, "yima hosfi tir hosfi hosfirpat")
+      , (54, "yima hosfi tir hosfi hosfihosf")
+      , (55, "yima hosfi tir hosfirpat")
+      , (56, "yima hosfi tir hosfirpati rpat")
+      , (57, "yima hosfi tir hosfirpati hosf")
+      , (58, "yima hosfi tir hosfirpati hosfirpat")
+      , (59, "yima hosfi tir hosfirpati hosfihosf")
+      , (60, "yima hosfirpat")
+      , (61, "yima hosfirpati rpat")
+      , (62, "yima hosfirpati hosf")
+      , (63, "yima hosfirpati hosfirpat")
+      , (64, "yima hosfirpati hosfihosf")
+      , (65, "yima hosfirpati tir yohtt")
+      , (66, "yima hosfirpati tir yohtti rpat")
+      , (67, "yima hosfirpati tir yohtti hosf")
+      , (68, "yima hosfirpati tir yohtti hosfirpat")
+      , (69, "yima hosfirpati tir yohtti hosfihosf")
+      , (70, "yima hosfirpati tir hosf")
+      , (71, "yima hosfirpati tir hosfi rpat")
+      , (72, "yima hosfirpati tir hosfi hosf")
+      , (73, "yima hosfirpati tir hosfi hosfirpat")
+      , (74, "yima hosfirpati tir hosfi hosfihosf")
+      , (75, "yima hosfirpati tir hosfirpat")
+      , (76, "yima hosfirpati tir hosfirpati rpat")
+      , (77, "yima hosfirpati tir hosfirpati hosf")
+      , (78, "yima hosfirpati tir hosfirpati hosfirpat")
+      , (79, "yima hosfirpati tir hosfirpati hosfihosf")
+      , (80, "yima hosfihosf")
+      , (81, "yima hosfihosfi rpat")
+      , (82, "yima hosfihosfi hosf")
+      , (83, "yima hosfihosfi hosfirpat")
+      , (84, "yima hosfihosfi hosfihosf")
+      , (85, "yima hosfihosfi tir yohtt")
+      , (86, "yima hosfihosfi tir yohtti rpat")
+      , (87, "yima hosfihosfi tir yohtti hosf")
+      , (88, "yima hosfihosfi tir yohtti hosfirpat")
+      , (89, "yima hosfihosfi tir yohtti hosfihosf")
+      , (90, "yima hosfihosfi tir hosf")
+      , (91, "yima hosfihosfi tir hosfi rpat")
+      , (92, "yima hosfihosfi tir hosfi hosf")
+      , (93, "yima hosfihosfi tir hosfi hosfirpat")
+      , (94, "yima hosfihosfi tir hosfi hosfihosf")
+      , (95, "yima hosfihosfi tir hosfirpat")
+      , (96, "yima hosfihosfi tir hosfirpati rpat")
+      , (97, "yima hosfihosfi tir hosfirpati hosf")
+      , (98, "yima hosfihosfi tir hosfirpati hosfirpat")
+      , (99, "yima hosfihosfi tir hosfirpati hosfihosf")
+      , (100, "yima tir yohtt")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/ARI/TestData.hs b/src-test/Text/Numeral/Language/ARI/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/ARI/TestData.hs
@@ -0,0 +1,203 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        ari
+
+[@Native name@]     -
+
+[@English name@]    Arikara
+-}
+module Text.Numeral.Language.ARI.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-arikara/en/ari/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "áxkux")
+      , (2, "pítkux")
+      , (3, "táwit")
+      , (4, "čiitíʾiš")
+      , (5, "šíhux")
+      , (6, "tšaápis")
+      , (7, "tawišaapiswaána")
+      , (8, "tawišaápis")
+      , (9, "nooxiniiwaána")
+      , (10, "nooxíniʾ")
+      , (11, "nooxini na áxkux")
+      , (12, "nooxini na pítkux")
+      , (13, "nooxini na táwit")
+      , (14, "nooxini na čiitíʾiš")
+      , (15, "nooxini na šíhux")
+      , (16, "nooxini na tšaápis")
+      , (17, "nooxini na tawišaapiswaána")
+      , (18, "nooxini na tawišaápis")
+      , (19, "nooxini na nooxiniiwaána")
+      , (20, "wiitáʾuʾ")
+      , (21, "wiitáʾu na áxkux")
+      , (22, "wiitáʾu na pítkux")
+      , (23, "wiitáʾu na táwit")
+      , (24, "wiitáʾu na čiitíʾiš")
+      , (25, "wiitáʾu na šíhux")
+      , (26, "wiitáʾu na tšaápis")
+      , (27, "wiitáʾu na tawišaapiswaána")
+      , (28, "wiitáʾu na tawišaápis")
+      , (29, "wiitáʾu na nooxiniiwaána")
+      , (30, "nasaawíʾuʾ")
+      , (31, "nasaawiʾu na áxkux")
+      , (32, "nasaawiʾu na pítkux")
+      , (33, "nasaawiʾu na táwit")
+      , (34, "nasaawiʾu na čiitíʾiš")
+      , (35, "nasaawiʾu na šíhux")
+      , (36, "nasaawiʾu na tšaápis")
+      , (37, "nasaawiʾu na tawišaapiswaána")
+      , (38, "nasaawiʾu na tawišaápis")
+      , (39, "nasaawiʾu na nooxiniiwaána")
+      , (40, "pitkuxunaánuʾ")
+      , (41, "pitkuxunaanu na áxkux")
+      , (42, "pitkuxunaanu na pítkux")
+      , (43, "pitkuxunaanu na táwit")
+      , (44, "pitkuxunaanu na čiitíʾiš")
+      , (45, "pitkuxunaanu na šíhux")
+      , (46, "pitkuxunaanu na tšaápis")
+      , (47, "pitkuxunaanu na tawišaapiswaána")
+      , (48, "pitkuxunaanu na tawišaápis")
+      , (49, "pitkuxunaanu na nooxiniiwaána")
+      , (50, "pitkuxunaánuʾ na nooxíniʾ")
+      , (51, "pitkuxunaanu na nooxini na áxkux")
+      , (52, "pitkuxunaanu na nooxini na pítkux")
+      , (53, "pitkuxunaanu na nooxini na táwit")
+      , (54, "pitkuxunaanu na nooxini na čiitíʾiš")
+      , (55, "pitkuxunaanu na nooxini na šíhux")
+      , (56, "pitkuxunaanu na nooxini na tšaápis")
+      , (57, "pitkuxunaanu na nooxini na tawišaapiswaána")
+      , (58, "pitkuxunaanu na nooxini na tawišaápis")
+      , (59, "pitkuxunaanu na nooxini na nooxiniiwaána")
+      , (60, "tawihkunaánuʾ")
+      , (61, "tawihkunaanu na áxkux")
+      , (62, "tawihkunaanu na pítkux")
+      , (63, "tawihkunaanu na táwit")
+      , (64, "tawihkunaanu na čiitíʾiš")
+      , (65, "tawihkunaanu na šíhux")
+      , (66, "tawihkunaanu na tšaápis")
+      , (67, "tawihkunaanu na tawišaapiswaána")
+      , (68, "tawihkunaanu na tawišaápis")
+      , (69, "tawihkunaanu na nooxiniiwaána")
+      , (70, "tawihkunaánuʾ na nooxíniʾ")
+      , (71, "tawihkunaánu nooxíni na áxkux")
+      , (72, "tawihkunaánu nooxíni na pítkux")
+      , (73, "tawihkunaánu nooxíni na táwit")
+      , (74, "tawihkunaánu nooxíni na čiitíʾiš")
+      , (75, "tawihkunaánu nooxíni na šíhux")
+      , (76, "tawihkunaánu nooxíni na tšaápis")
+      , (77, "tawihkunaánu nooxíni na tawišaapiswaána")
+      , (78, "tawihkunaánu nooxíni na tawišaápis")
+      , (79, "tawihkunaánu nooxíni na nooxiniiwaána")
+      , (80, "čiitiʾištaánuʾ")
+      , (81, "čiitiʾištaanu na áxkux")
+      , (82, "čiitiʾištaanu na pítkux")
+      , (83, "čiitiʾištaanu na táwit")
+      , (84, "čiitiʾištaanu na čiitíʾiš")
+      , (85, "čiitiʾištaanu na šíhux")
+      , (86, "čiitiʾištaanu na tšaápis")
+      , (87, "čiitiʾištaanu na tawišaapiswaána")
+      , (88, "čiitiʾištaanu na tawišaápis")
+      , (89, "čiitiʾištaanu na nooxiniiwaána")
+      , (90, "čiitiʾištaanu na nooxíniʾ")
+      , (91, "čiitiʾištaanu nooxíni na áxkux")
+      , (92, "čiitiʾištaanu nooxíni na pítkux")
+      , (93, "čiitiʾištaanu nooxíni na táwit")
+      , (94, "čiitiʾištaanu nooxíni na čiitíʾiš")
+      , (95, "čiitiʾištaanu nooxíni na šíhux")
+      , (96, "čiitiʾištaanu nooxíni na tšaápis")
+      , (97, "čiitiʾištaanu nooxíni na tawišaapiswaána")
+      , (98, "čiitiʾištaanu nooxíni na tawišaápis")
+      , (99, "čiitiʾištaanu nooxíni na nooxiniiwaána")
+      , (100, "šihuxtaánuʾ")
+      , (101, "šihuxtaánuʾ na áxkux")
+      , (102, "šihuxtaánuʾ na pítkux")
+      , (103, "šihuxtaánuʾ na táwit")
+      , (104, "šihuxtaánuʾ na čiitíʾiš")
+      , (105, "šihuxtaánuʾ na šíhux")
+      , (106, "šihuxtaánuʾ na tšaápis")
+      , (107, "šihuxtaánuʾ na tawišaapiswaána")
+      , (108, "šihuxtaánuʾ na tawišaápis")
+      , (109, "šihuxtaánuʾ na nooxiniiwaána")
+      , (110, "šihuxtaánuʾ na nooxíniʾ")
+      , (123, "šihuxtaánuʾ na wiitáʾu na táwit")
+      , (200, "pitkux šihuxtaánuʾ")
+      , (300, "tawit šihuxtaánuʾ")
+      , (321, "tawit šihuxtaánuʾ na wiitáʾu na áxkux")
+      , (400, "čiitiʾiš šihuxtaánuʾ")
+      , (500, "šíhux šihuxtaánuʾ")
+      , (600, "tšaápis šihuxtaánuʾ")
+      , (700, "tawišaapiswaána šihuxtaánuʾ")
+      , (800, "tawišaápis šihuxtaánuʾ")
+      , (900, "nooxiniiwaána šihuxtaánuʾ")
+      , (909, "nooxiniiwaána šihuxtaánuʾ na nooxiniiwaána")
+      , (990, "nooxiniiwaána šihuxtaánuʾ na čiitiʾištaanu na nooxíniʾ")
+      , (999, "nooxiniiwaána šihuxtaánuʾ na čiitiʾištaanu nooxíni na nooxiniiwaána")
+      , (1000, "nooxininaánuʾ")
+      , (1001, "nooxininaánuʾ na áxkux")
+      , (1008, "nooxininaánuʾ na tawišaápis")
+      , (1234, "nooxininaánuʾ na pitkux šihuxtaánuʾ na nasaawiʾu na čiitíʾiš")
+      , (2000, "pitkux nooxininaánuʾ")
+      , (3000, "tawit nooxininaánuʾ")
+      , (4000, "čiitiʾiš nooxininaánuʾ")
+      , (4321, "čiitiʾiš nooxininaánuʾ na tawit šihuxtaánuʾ na wiitáʾu na áxkux")
+      , (5000, "šíhux nooxininaánuʾ")
+      , (6000, "tšaápis nooxininaánuʾ")
+      , (7000, "tawišaapiswaána nooxininaánuʾ")
+      , (8000, "tawišaápis nooxininaánuʾ")
+      , (9000, "nooxiniiwaána nooxininaánuʾ")
+      , (10000, "nooxíniʾ nooxininaánuʾ")
+      , (12345, "nooxini na pitkux nooxininaánuʾ na tawit šihuxtaánuʾ na pitkuxunaanu na šíhux")
+      , (20000, "wiitáʾuʾ nooxininaánuʾ")
+      , (30000, "nasaawíʾuʾ nooxininaánuʾ")
+      , (40000, "pitkuxunaánuʾ nooxininaánuʾ")
+      , (50000, "pitkuxunaánuʾ na nooxíniʾ nooxininaánuʾ")
+      , (54321, "pitkuxunaanu na nooxini na čiitiʾiš nooxininaánuʾ na tawit šihuxtaánuʾ na wiitáʾu na áxkux")
+      , (60000, "tawihkunaánuʾ nooxininaánuʾ")
+      , (70000, "tawihkunaánuʾ na nooxíniʾ nooxininaánuʾ")
+      , (80000, "čiitiʾištaánuʾ nooxininaánuʾ")
+      , (90000, "čiitiʾištaanu na nooxíniʾ nooxininaánuʾ")
+      , (100000, "šihuxtaánuʾ nooxininaánuʾ")
+      , (123456, "šihuxtaánuʾ na wiitáʾu na tawit nooxininaánuʾ na čiitiʾiš šihuxtaánuʾ na pitkuxunaanu na nooxini na tšaápis")
+      , (200000, "pitkux šihuxtaánuʾ nooxininaánuʾ")
+      , (300000, "tawit šihuxtaánuʾ nooxininaánuʾ")
+      , (400000, "čiitiʾiš šihuxtaánuʾ nooxininaánuʾ")
+      , (500000, "šíhux šihuxtaánuʾ nooxininaánuʾ")
+      , (600000, "tšaápis šihuxtaánuʾ nooxininaánuʾ")
+      , (654321, "tšaápis šihuxtaánuʾ na pitkuxunaanu na nooxini na čiitiʾiš nooxininaánuʾ na tawit šihuxtaánuʾ na wiitáʾu na áxkux")
+      , (700000, "tawišaapiswaána šihuxtaánuʾ nooxininaánuʾ")
+      , (800000, "tawišaápis šihuxtaánuʾ nooxininaánuʾ")
+      , (900000, "nooxiniiwaána šihuxtaánuʾ nooxininaánuʾ")
+      , (1000000, "axku-hunaánuʾ")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/AST/TestData.hs b/src-test/Text/Numeral/Language/AST/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/AST/TestData.hs
@@ -0,0 +1,204 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        ast
+
+[@ISO639-3@]        ast
+
+[@Native name@]     asturianu
+
+[@English name@]    Asturian
+-}
+module Text.Numeral.Language.AST.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-asturian/en/ast/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "ceru")
+      , (1, "un")
+      , (2, "dos")
+      , (3, "tres")
+      , (4, "cuatro")
+      , (5, "cinco")
+      , (6, "seis")
+      , (7, "siete")
+      , (8, "ocho")
+      , (9, "nueve")
+      , (10, "diez")
+      , (11, "once")
+      , (12, "doce")
+      , (13, "trece")
+      , (14, "catorce")
+      , (15, "quince")
+      , (16, "deciséis")
+      , (17, "decisiete")
+      , (18, "deciocho")
+      , (19, "decinueve")
+      , (20, "venti")
+      , (21, "ventiún")
+      , (22, "ventidós")
+      , (23, "ventitrés")
+      , (24, "venticuatro")
+      , (25, "venticinco")
+      , (26, "ventiséis")
+      , (27, "ventisiete")
+      , (28, "ventiocho")
+      , (29, "ventinueve")
+      , (30, "trenta")
+      , (31, "trenta y un")
+      , (32, "trenta y dos")
+      , (33, "trenta y tres")
+      , (34, "trenta y cuatro")
+      , (35, "trenta y cinco")
+      , (36, "trenta y seis")
+      , (37, "trenta y siete")
+      , (38, "trenta y ocho")
+      , (39, "trenta y nueve")
+      , (40, "cuaranta")
+      , (41, "cuaranta y un")
+      , (42, "cuaranta y dos")
+      , (43, "cuaranta y tres")
+      , (44, "cuaranta y cuatro")
+      , (45, "cuaranta y cinco")
+      , (46, "cuaranta y seis")
+      , (47, "cuaranta y siete")
+      , (48, "cuaranta y ocho")
+      , (49, "cuaranta y nueve")
+      , (50, "cincuenta")
+      , (51, "cincuenta y un")
+      , (52, "cincuenta y dos")
+      , (53, "cincuenta y tres")
+      , (54, "cincuenta y cuatro")
+      , (55, "cincuenta y cinco")
+      , (56, "cincuenta y seis")
+      , (57, "cincuenta y siete")
+      , (58, "cincuenta y ocho")
+      , (59, "cincuenta y nueve")
+      , (60, "sesenta")
+      , (61, "sesenta y un")
+      , (62, "sesenta y dos")
+      , (63, "sesenta y tres")
+      , (64, "sesenta y cuatro")
+      , (65, "sesenta y cinco")
+      , (66, "sesenta y seis")
+      , (67, "sesenta y siete")
+      , (68, "sesenta y ocho")
+      , (69, "sesenta y nueve")
+      , (70, "setanta")
+      , (71, "setanta y un")
+      , (72, "setanta y dos")
+      , (73, "setanta y tres")
+      , (74, "setanta y cuatro")
+      , (75, "setanta y cinco")
+      , (76, "setanta y seis")
+      , (77, "setanta y siete")
+      , (78, "setanta y ocho")
+      , (79, "setanta y nueve")
+      , (80, "ochenta")
+      , (81, "ochenta y un")
+      , (82, "ochenta y dos")
+      , (83, "ochenta y tres")
+      , (84, "ochenta y cuatro")
+      , (85, "ochenta y cinco")
+      , (86, "ochenta y seis")
+      , (87, "ochenta y siete")
+      , (88, "ochenta y ocho")
+      , (89, "ochenta y nueve")
+      , (90, "noventa")
+      , (91, "noventa y un")
+      , (92, "noventa y dos")
+      , (93, "noventa y tres")
+      , (94, "noventa y cuatro")
+      , (95, "noventa y cinco")
+      , (96, "noventa y seis")
+      , (97, "noventa y siete")
+      , (98, "noventa y ocho")
+      , (99, "noventa y nueve")
+      , (100, "cien")
+      , (101, "cien un")
+      , (102, "cien dos")
+      , (103, "cien tres")
+      , (104, "cien cuatro")
+      , (105, "cien cinco")
+      , (106, "cien seis")
+      , (107, "cien siete")
+      , (108, "cien ocho")
+      , (109, "cien nueve")
+      , (110, "cien diez")
+      , (123, "cien ventitrés")
+      , (200, "doscientos")
+      , (300, "trescientos")
+      , (321, "trescientos ventiún")
+      , (400, "cuatrocientos")
+      , (500, "quinientos")
+      , (600, "seiscientos")
+      , (700, "setecientos")
+      , (800, "ochocientos")
+      , (900, "novecientos")
+      , (909, "novecientos nueve")
+      , (990, "novecientos noventa")
+      , (999, "novecientos noventa y nueve")
+      , (1000, "mil")
+      , (1001, "mil un")
+      , (1008, "mil ocho")
+      , (1234, "mil doscientos trenta y cuatro")
+      , (2000, "dos mil")
+      , (3000, "tres mil")
+      , (4000, "cuatro mil")
+      , (4321, "cuatro mil trescientos ventiún")
+      , (5000, "cinco mil")
+      , (6000, "seis mil")
+      , (7000, "siete mil")
+      , (8000, "ocho mil")
+      , (9000, "nueve mil")
+      , (10000, "diez mil")
+      , (12345, "doce mil trescientos cuaranta y cinco")
+      , (20000, "venti mil")
+      , (30000, "trenta mil")
+      , (40000, "cuaranta mil")
+      , (50000, "cincuenta mil")
+      , (54321, "cincuenta y cuatro mil trescientos ventiún")
+      , (60000, "sesenta mil")
+      , (70000, "setanta mil")
+      , (80000, "ochenta mil")
+      , (90000, "noventa mil")
+      , (100000, "cien mil")
+      , (123456, "cien ventitrés mil cuatrocientos cincuenta y seis")
+      , (200000, "doscientos mil")
+      , (300000, "trescientos mil")
+      , (400000, "cuatrocientos mil")
+      , (500000, "quinientos mil")
+      , (600000, "seiscientos mil")
+      , (654321, "seiscientos cincuenta y cuatro mil trescientos ventiún")
+      , (700000, "setecientos mil")
+      , (800000, "ochocientos mil")
+      , (900000, "novecientos mil")
+      , (1000000, "un millón")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/AZ/TestData.hs b/src-test/Text/Numeral/Language/AZ/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/AZ/TestData.hs
@@ -0,0 +1,206 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        az
+
+[@ISO639-2@]        aze
+
+[@ISO639-3@]        aze
+
+[@Native name@]     Azərbaycanca
+
+[@English name@]    Azerbaijani
+-}
+module Text.Numeral.Language.AZ.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-azerbaijani/en/aze/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "sıfır")
+      , (1, "bir")
+      , (2, "iki")
+      , (3, "üç")
+      , (4, "dörd")
+      , (5, "beş")
+      , (6, "altı")
+      , (7, "yeddi")
+      , (8, "səkkiz")
+      , (9, "doqquz")
+      , (10, "on")
+      , (11, "on bir")
+      , (12, "on iki")
+      , (13, "on uç")
+      , (14, "on dörd")
+      , (15, "on beş")
+      , (16, "on altı")
+      , (17, "on yeddi")
+      , (18, "on səkkiz")
+      , (19, "on doqquz")
+      , (20, "iyirmi")
+      , (21, "iyirmi bir")
+      , (22, "iyirmi iki")
+      , (23, "iyirmi uç")
+      , (24, "iyirmi dörd")
+      , (25, "iyirmi beş")
+      , (26, "iyirmi altı")
+      , (27, "iyirmi yeddi")
+      , (28, "iyirmi səkkiz")
+      , (29, "iyirmi doqquz")
+      , (30, "otuz")
+      , (31, "otuz bir")
+      , (32, "otuz iki")
+      , (33, "otuz uç")
+      , (34, "otuz dörd")
+      , (35, "otuz beş")
+      , (36, "otuz altı")
+      , (37, "otuz yeddi")
+      , (38, "otuz səkkiz")
+      , (39, "otuz doqquz")
+      , (40, "qırx")
+      , (41, "qırx bir")
+      , (42, "qırx iki")
+      , (43, "qırx uç")
+      , (44, "qırx dörd")
+      , (45, "qırx beş")
+      , (46, "qırx altı")
+      , (47, "qırx yeddi")
+      , (48, "qırx səkkiz")
+      , (49, "qırx doqquz")
+      , (50, "əlli")
+      , (51, "əlli bir")
+      , (52, "əlli iki")
+      , (53, "əlli uç")
+      , (54, "əlli dörd")
+      , (55, "əlli beş")
+      , (56, "əlli altı")
+      , (57, "əlli yeddi")
+      , (58, "əlli səkkiz")
+      , (59, "əlli doqquz")
+      , (60, "altmış")
+      , (61, "altmış bir")
+      , (62, "altmış iki")
+      , (63, "altmış uç")
+      , (64, "altmış dörd")
+      , (65, "altmış beş")
+      , (66, "altmış altı")
+      , (67, "altmış yeddi")
+      , (68, "altmış səkkiz")
+      , (69, "altmış doqquz")
+      , (70, "yetmiş")
+      , (71, "yetmiş bir")
+      , (72, "yetmiş iki")
+      , (73, "yetmiş uç")
+      , (74, "yetmiş dörd")
+      , (75, "yetmiş beş")
+      , (76, "yetmiş altı")
+      , (77, "yetmiş yeddi")
+      , (78, "yetmiş səkkiz")
+      , (79, "yetmiş doqquz")
+      , (80, "səksən")
+      , (81, "səksən bir")
+      , (82, "səksən iki")
+      , (83, "səksən uç")
+      , (84, "səksən dörd")
+      , (85, "səksən beş")
+      , (86, "səksən altı")
+      , (87, "səksən yeddi")
+      , (88, "səksən səkkiz")
+      , (89, "səksən doqquz")
+      , (90, "doxsan")
+      , (91, "doxsan bir")
+      , (92, "doxsan iki")
+      , (93, "doxsan uç")
+      , (94, "doxsan dörd")
+      , (95, "doxsan beş")
+      , (96, "doxsan altı")
+      , (97, "doxsan yeddi")
+      , (98, "doxsan səkkiz")
+      , (99, "doxsan doqquz")
+      , (100, "yüz")
+      , (101, "yüz bir")
+      , (102, "yüz iki")
+      , (103, "yüz uç")
+      , (104, "yüz dörd")
+      , (105, "yüz beş")
+      , (106, "yüz altı")
+      , (107, "yüz yeddi")
+      , (108, "yüz səkkiz")
+      , (109, "yüz doqquz")
+      , (110, "yüz on")
+      , (123, "yüz iyirmi uç")
+      , (200, "iki yüz")
+      , (300, "üç yüz")
+      , (321, "üç yüz iyirmi bir")
+      , (400, "dörd yüz")
+      , (500, "beş yüz")
+      , (600, "altı yüz")
+      , (700, "yeddi yüz")
+      , (800, "səkkiz yüz")
+      , (900, "doqquz yüz")
+      , (909, "doqquz yüz doqquz")
+      , (990, "doqquz yüz doxsan")
+      , (999, "doqquz yüz doxsan doqquz")
+      , (1000, "bir min")
+      , (1001, "bir min bir")
+      , (1008, "bir min səkkiz")
+      , (1234, "bir min iki yüz otuz dörd")
+      , (2000, "iki min")
+      , (3000, "üç min")
+      , (4000, "dörd min")
+      , (4321, "dörd min üç yüz iyirmi bir")
+      , (5000, "beş min")
+      , (6000, "altı min")
+      , (7000, "yeddi min")
+      , (8000, "səkkiz min")
+      , (9000, "doqquz min")
+      , (10000, "on min")
+      , (12345, "oniki min üç yüz qırx beş")
+      , (20000, "iyirmi min")
+      , (30000, "otuz min")
+      , (40000, "qırx min")
+      , (50000, "əlli min")
+      , (54321, "əlli dörd min üç yüz iyirmi bir")
+      , (60000, "altmış min")
+      , (70000, "yetmiş min")
+      , (80000, "səksən min")
+      , (90000, "doxsan min")
+      , (100000, "yüz min")
+      , (123456, "yüz iyirmi üç min dörd yüz əlli altı")
+      , (200000, "iki yüz min")
+      , (300000, "üç yüz min")
+      , (400000, "dörd yüz min")
+      , (500000, "beş yüz min")
+      , (600000, "altı yüz min")
+      , (654321, "altı yüz əlli dörd min üç yüz iyirmi bir")
+      , (700000, "yeddi yüz min")
+      , (800000, "səkkiz yüz min")
+      , (900000, "doqquz yüz min")
+      , (1000000, "bir milyon")
+      , (1000000000, "bir milyar")
+      , (1000000000000, "bir trilyon")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/BA/TestData.hs b/src-test/Text/Numeral/Language/BA/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/BA/TestData.hs
@@ -0,0 +1,180 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        ba
+
+[@ISO639-2@]        bak
+
+[@ISO639-3@]        bak
+
+[@Native name@]     Башҡорт теле
+
+[@English name@]    Bashkir
+-}
+module Text.Numeral.Language.BA.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-bashkir/en/bak/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "бер")
+      , (2, "ике")
+      , (3, "өс")
+      , (4, "дүрт")
+      , (5, "биш")
+      , (6, "алты")
+      , (7, "ете")
+      , (8, "һигеҙ")
+      , (9, "туғыҙ")
+      , (10, "ун")
+      , (11, "ун бер")
+      , (12, "ун ике")
+      , (13, "ун өс")
+      , (14, "ун дүрт")
+      , (15, "ун биш")
+      , (16, "ун алты")
+      , (17, "ун ете")
+      , (18, "ун һигеҙ")
+      , (19, "ун туғыҙ")
+      , (20, "егерме")
+      , (21, "егерме бер")
+      , (22, "егерме ике")
+      , (23, "егерме өс")
+      , (24, "егерме дүрт")
+      , (25, "егерме биш")
+      , (26, "егерме алты")
+      , (27, "егерме ете")
+      , (28, "егерме һигеҙ")
+      , (29, "егерме туғыҙ")
+      , (30, "утыҙ")
+      , (31, "утыҙ бер")
+      , (32, "утыҙ ике")
+      , (33, "утыҙ өс")
+      , (34, "утыҙ дүрт")
+      , (35, "утыҙ биш")
+      , (36, "утыҙ алты")
+      , (37, "утыҙ ете")
+      , (38, "утыҙ һигеҙ")
+      , (39, "утыҙ туғыҙ")
+      , (40, "ҡырҡ")
+      , (41, "ҡырҡ бер")
+      , (42, "ҡырҡ ике")
+      , (43, "ҡырҡ өс")
+      , (44, "ҡырҡ дүрт")
+      , (45, "ҡырҡ биш")
+      , (46, "ҡырҡ алты")
+      , (47, "ҡырҡ ете")
+      , (48, "ҡырҡ һигеҙ")
+      , (49, "ҡырҡ туғыҙ")
+      , (50, "илле")
+      , (51, "илле бер")
+      , (52, "илле ике")
+      , (53, "илле өс")
+      , (54, "илле дүрт")
+      , (55, "илле биш")
+      , (56, "илле алты")
+      , (57, "илле ете")
+      , (58, "илле һигеҙ")
+      , (59, "илле туғыҙ")
+      , (60, "алтмыш")
+      , (61, "алтмыш бер")
+      , (62, "алтмыш ике")
+      , (63, "алтмыш өс")
+      , (64, "алтмыш дүрт")
+      , (65, "алтмыш биш")
+      , (66, "алтмыш алты")
+      , (67, "алтмыш ете")
+      , (68, "алтмыш һигеҙ")
+      , (69, "алтмыш туғыҙ")
+      , (70, "етмеш")
+      , (71, "етмеш бер")
+      , (72, "етмеш ике")
+      , (73, "етмеш өс")
+      , (74, "етмеш дүрт")
+      , (75, "етмеш биш")
+      , (76, "етмеш алты")
+      , (77, "етмеш ете")
+      , (78, "етмеш һигеҙ")
+      , (79, "етмеш туғыҙ")
+      , (80, "һикһән")
+      , (81, "һикһән бер")
+      , (82, "һикһән ике")
+      , (83, "һикһән өс")
+      , (84, "һикһән дүрт")
+      , (85, "һикһән биш")
+      , (86, "һикһән алты")
+      , (87, "һикһән ете")
+      , (88, "һикһән һигеҙ")
+      , (89, "һикһән туғыҙ")
+      , (90, "туҡһан")
+      , (91, "туҡһан бер")
+      , (92, "туҡһан ике")
+      , (93, "туҡһан өс")
+      , (94, "туҡһан дүрт")
+      , (95, "туҡһан биш")
+      , (96, "туҡһан алты")
+      , (97, "туҡһан ете")
+      , (98, "туҡһан һигеҙ")
+      , (99, "туҡһан туғыҙ")
+      , (100, "йөҙ")
+      , (101, "йөҙ бер")
+      , (102, "йөҙ ике")
+      , (103, "йөҙ өс")
+      , (104, "йөҙ дүрт")
+      , (105, "йөҙ биш")
+      , (106, "йөҙ алты")
+      , (107, "йөҙ ете")
+      , (108, "йөҙ һигеҙ")
+      , (109, "йөҙ туғыҙ")
+      , (110, "йөҙ ун")
+      , (123, "йөҙ егерме өс")
+      , (200, "ике йөҙ")
+      , (300, "өс йөҙ")
+      , (321, "өс йөҙ егерме бер")
+      , (400, "дүрт йөҙ")
+      , (500, "биш йөҙ")
+      , (600, "алты йөҙ")
+      , (700, "ете йөҙ")
+      , (800, "һигеҙ йөҙ")
+      , (900, "туғыҙ йөҙ")
+      , (909, "туғыҙ йөҙ туғыҙ")
+      , (990, "туғыҙ йөҙ туҡһан")
+      , (999, "туғыҙ йөҙ туҡһан туғыҙ")
+      , (1000, "мең")
+      , (1001, "мең бер")
+      , (1008, "мең һигеҙ")
+      , (1234, "мең ике йөҙ утыҙ дүрт")
+      , (2000, "ике мең")
+      , (3000, "өс мең")
+      , (4000, "дүрт мең")
+      , (4321, "дүрт мең өс йөҙ егерме бер")
+      , (5000, "биш мең")
+      , (6000, "алты мең")
+      , (7000, "ете мең")
+      , (8000, "һигеҙ мең")
+      , (9000, "туғыҙ мең")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/BG/TestData.hs b/src-test/Text/Numeral/Language/BG/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/BG/TestData.hs
@@ -0,0 +1,237 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        bg
+
+[@ISO639-2@]        bul
+
+[@ISO639-3@]        bul
+
+[@Native name@]     български език
+
+[@English name@]    Bulgarian
+-}
+
+module Text.Numeral.Language.BG.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral, (+) )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Grammar
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-bulgarian/en/bul/
+  http://en.wikipedia.org/wiki/Bulgarian_grammar#Numbers
+  http://bg.wikipedia.org/wiki/Имена_на_числата
+-}
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "neuter"
+    , neuter defaultInflection
+    , [ (-3, "минус три")
+      , (0, "нула")
+      , (1, "едно")
+      , (2, "две")
+      , (3, "три")
+      , (4, "четири")
+      , (5, "пет")
+      , (6, "шест")
+      , (7, "седем")
+      , (8, "осем")
+      , (9, "девет")
+      , (10, "десет")
+      , (11, "единадесет")
+      , (12, "дванадесет")
+      , (13, "тринадесет")
+      , (14, "четиринадесет")
+      , (15, "петнадесет")
+      , (16, "шестнадесет")
+      , (17, "седемнадесет")
+      , (18, "осемнадесет")
+      , (19, "деветнадесет")
+      , (20, "двадесет")
+      , (21, "двадесет и едно")
+      , (22, "двадесет и две")
+      , (23, "двадесет и три")
+      , (24, "двадесет и четири")
+      , (25, "двадесет и пет")
+      , (26, "двадесет и шест")
+      , (27, "двадесет и седем")
+      , (28, "двадесет и осем")
+      , (29, "двадесет и девет")
+      , (30, "тридесет")
+      , (31, "тридесет и едно")
+      , (32, "тридесет и две")
+      , (33, "тридесет и три")
+      , (34, "тридесет и четири")
+      , (35, "тридесет и пет")
+      , (36, "тридесет и шест")
+      , (37, "тридесет и седем")
+      , (38, "тридесет и осем")
+      , (39, "тридесет и девет")
+      , (40, "четиридесет")
+      , (41, "четиридесет и едно")
+      , (42, "четиридесет и две")
+      , (43, "четиридесет и три")
+      , (44, "четиридесет и четири")
+      , (45, "четиридесет и пет")
+      , (46, "четиридесет и шест")
+      , (47, "четиридесет и седем")
+      , (48, "четиридесет и осем")
+      , (49, "четиридесет и девет")
+      , (50, "петдесет")
+      , (51, "петдесет и едно")
+      , (52, "петдесет и две")
+      , (53, "петдесет и три")
+      , (54, "петдесет и четири")
+      , (55, "петдесет и пет")
+      , (56, "петдесет и шест")
+      , (57, "петдесет и седем")
+      , (58, "петдесет и осем")
+      , (59, "петдесет и девет")
+      , (60, "шестдесет")
+      , (61, "шестдесет и едно")
+      , (62, "шестдесет и две")
+      , (63, "шестдесет и три")
+      , (64, "шестдесет и четири")
+      , (65, "шестдесет и пет")
+      , (66, "шестдесет и шест")
+      , (67, "шестдесет и седем")
+      , (68, "шестдесет и осем")
+      , (69, "шестдесет и девет")
+      , (70, "седемдесет")
+      , (71, "седемдесет и едно")
+      , (72, "седемдесет и две")
+      , (73, "седемдесет и три")
+      , (74, "седемдесет и четири")
+      , (75, "седемдесет и пет")
+      , (76, "седемдесет и шест")
+      , (77, "седемдесет и седем")
+      , (78, "седемдесет и осем")
+      , (79, "седемдесет и девет")
+      , (80, "осемдесет")
+      , (81, "осемдесет и едно")
+      , (82, "осемдесет и две")
+      , (83, "осемдесет и три")
+      , (84, "осемдесет и четири")
+      , (85, "осемдесет и пет")
+      , (86, "осемдесет и шест")
+      , (87, "осемдесет и седем")
+      , (88, "осемдесет и осем")
+      , (89, "осемдесет и девет")
+      , (90, "деветдесет")
+      , (91, "деветдесет и едно")
+      , (92, "деветдесет и две")
+      , (93, "деветдесет и три")
+      , (94, "деветдесет и четири")
+      , (95, "деветдесет и пет")
+      , (96, "деветдесет и шест")
+      , (97, "деветдесет и седем")
+      , (98, "деветдесет и осем")
+      , (99, "деветдесет и девет")
+      , (100, "сто")
+      , (101, "сто и едно")
+      , (102, "сто и две")
+      , (110, "сто и десет")
+      , (115, "сто и петнадесет")
+      , (120, "сто и двадесет")
+      , (121, "сто двадесет и едно")
+      , (130, "сто и тридесет")
+      , (133, "сто тридесет и три")
+      , (200, "двеста")
+      , (202, "двеста и две")
+      , (216, "двеста и шестнадесет")
+      , (265, "двеста шестдесет и пет")
+      , (300, "триста")
+      , (400, "четиристотин")
+      , (500, "петстотин")
+      , (507, "петстотин и седем")
+      , (600, "шестстотин")
+      , (700, "седемстотин")
+      , (800, "осемстотин")
+      , (900, "деветстотин")
+      , (1000, "хиляда")
+      , (1234, "хиляда двеста тридесет и четири")
+      , (2000, "две хиляди")
+      , (3000, "три хиляди")
+      , (5000, "пет хиляди")
+      , (6000, "шест хиляди")
+      , (9000, "девет хиляди")
+      , (16000, "шестнадесет хиляди")
+      , (21000, "двадесет и едно хиляди")
+      , (22000, "двадесет и две хиляди")
+      , (22136, "двадесет и две хиляди сто тридесет и шест")
+      , (23000, "двадесет и три хиляди")
+      , (28000, "двадесет и осем хиляди")
+      , (41000, "четиридесет и едно хиляди")
+      , (42000, "четиридесет и две хиляди")
+      , (49000, "четиридесет и девет хиляди")
+      , (100000, "сто хиляди")
+      , (200000, "двеста хиляди")
+      , (255383, "двеста петдесет и пет хиляди триста осемдесет и три")
+      , (300000, "триста хиляди")
+      , (300001, "триста хиляди и едно")
+      , (300020, "триста хиляди и двадесет")
+      , (300825, "триста хиляди осемстотин двадесет и пет")
+      , (dec 6, "един милион")
+      , (1300825, "един милион триста хиляди осемстотин двадесет и пет")
+      , (1021000, "един милион двадесет и едно хиляди")
+      , (1001234, "един милион хиляда двеста тридесет и четири")
+      , (1000216, "един милион двеста и шестнадесет")
+      , (1000074, "един милион седемдесет и четири")
+      , (1000004, "един милион и четири")
+      , (2 ⋅ dec 6, "два милиона")
+      , (5 ⋅ dec 6, "пет милиона")
+      , (dec 9, "един милиард")
+      , (2 ⋅ dec 9, "два милиарда")
+      , (3 ⋅ dec 12, "три трилиона")
+      , (dec 15, "един квадрилион")
+      , (15 ⋅ dec 15 + 41, "петнадесет квадрилиона четиридесет и едно")
+      , (dec 18, "един квинтилион")
+      , (dec 21, "един секстилион")
+      , (dec 24, "един септилион")
+      , (dec 27, "един октилион")
+      , (dec 30, "един нонилион")
+      , (dec 33, "един децилион")
+      , (dec 36, "един индецилион")
+      , (dec 39, "един дуодецилион")
+      , (dec 42, "един тридецилион")
+      , (dec 45, "един куадродецилион")
+      , (900 ⋅ dec 45, "деветстотин куадродецилиона")
+      ]
+    )
+    , ( "feminine"
+      , feminine defaultInflection
+      , [ (1, "една")
+        , (2, "две")
+        , (200, "двеста")
+        , (202, "двеста и две")
+        ]
+      )
+    , ( "masculine"
+      , masculine defaultInflection
+      , [ (1, "един")
+        , (2, "два")
+        , (200, "двеста")
+        , (202, "двеста и два")
+        ]
+      )
+  ]
diff --git a/src-test/Text/Numeral/Language/BM/TestData.hs b/src-test/Text/Numeral/Language/BM/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/BM/TestData.hs
@@ -0,0 +1,203 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        bm
+
+[@ISO639-2@]        bam
+
+[@ISO639-3@]        bam
+
+[@Native name@]     -
+
+[@English name@]    Bambara
+-}
+module Text.Numeral.Language.BM.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-bambara/en/bam/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "kélen")
+      , (2, "fila")
+      , (3, "sàba")
+      , (4, "náani")
+      , (5, "dúuru")
+      , (6, "wɔɔrɔ")
+      , (7, "wólonwula")
+      , (8, "séegin")
+      , (9, "k̀ɔnɔntɔn")
+      , (10, "tán")
+      , (11, "tán ní kélen")
+      , (12, "tán ní fila")
+      , (13, "tán ní sàba")
+      , (14, "tán ní náani")
+      , (15, "tán ní dúuru")
+      , (16, "tán ní wɔɔrɔ")
+      , (17, "tán ní wólonwula")
+      , (18, "tán ní séegin")
+      , (19, "tán ní k̀ɔnɔntɔn")
+      , (20, "mùgan")
+      , (21, "mùgan ní kélen")
+      , (22, "mùgan ní fila")
+      , (23, "mùgan ní sàba")
+      , (24, "mùgan ní náani")
+      , (25, "mùgan ní dúuru")
+      , (26, "mùgan ní wɔɔrɔ")
+      , (27, "mùgan ní wólonwula")
+      , (28, "mùgan ní séegin")
+      , (29, "mùgan ní k̀ɔnɔntɔn")
+      , (30, "bísàba")
+      , (31, "bísàba ní kélen")
+      , (32, "bísàba ní fila")
+      , (33, "bísàba ní sàba")
+      , (34, "bísàba ní náani")
+      , (35, "bísàba ní dúuru")
+      , (36, "bísàba ní wɔɔrɔ")
+      , (37, "bísàba ní wólonwula")
+      , (38, "bísàba ní séegin")
+      , (39, "bísàba ní k̀ɔnɔntɔn")
+      , (40, "bínaani")
+      , (41, "bínaani ní kélen")
+      , (42, "bínaani ní fila")
+      , (43, "bínaani ní sàba")
+      , (44, "bínaani ní náani")
+      , (45, "bínaani ní dúuru")
+      , (46, "bínaani ní wɔɔrɔ")
+      , (47, "bínaani ní wólonwula")
+      , (48, "bínaani ní séegin")
+      , (49, "bínaani ní k̀ɔnɔntɔn")
+      , (50, "bídúuru")
+      , (51, "bídúuru ní kélen")
+      , (52, "bídúuru ní fila")
+      , (53, "bídúuru ní sàba")
+      , (54, "bídúuru ní náani")
+      , (55, "bídúuru ní dúuru")
+      , (56, "bídúuru ní wɔɔrɔ")
+      , (57, "bídúuru ní wólonwula")
+      , (58, "bídúuru ní séegin")
+      , (59, "bídúuru ní k̀ɔnɔntɔn")
+      , (60, "bíwɔɔrɔ")
+      , (61, "bíwɔɔrɔ ní kélen")
+      , (62, "bíwɔɔrɔ ní fila")
+      , (63, "bíwɔɔrɔ ní sàba")
+      , (64, "bíwɔɔrɔ ní náani")
+      , (65, "bíwɔɔrɔ ní dúuru")
+      , (66, "bíwɔɔrɔ ní wɔɔrɔ")
+      , (67, "bíwɔɔrɔ ní wólonwula")
+      , (68, "bíwɔɔrɔ ní séegin")
+      , (69, "bíwɔɔrɔ ní k̀ɔnɔntɔn")
+      , (70, "bíwolonfila")
+      , (71, "bíwolonfila ní kélen")
+      , (72, "bíwolonfila ní fila")
+      , (73, "bíwolonfila ní sàba")
+      , (74, "bíwolonfila ní náani")
+      , (75, "bíwolonfila ní dúuru")
+      , (76, "bíwolonfila ní wɔɔrɔ")
+      , (77, "bíwolonfila ní wólonwula")
+      , (78, "bíwolonfila ní séegin")
+      , (79, "bíwolonfila ní k̀ɔnɔntɔn")
+      , (80, "bíséegin")
+      , (81, "bíséegin ní kélen")
+      , (82, "bíséegin ní fila")
+      , (83, "bíséegin ní sàba")
+      , (84, "bíséegin ní náani")
+      , (85, "bíséegin ní dúuru")
+      , (86, "bíséegin ní wɔɔrɔ")
+      , (87, "bíséegin ní wólonwula")
+      , (88, "bíséegin ní séegin")
+      , (89, "bíséegin ní k̀ɔnɔntɔn")
+      , (90, "bík̀ɔnɔntɔn")
+      , (91, "bík̀ɔnɔntɔn ní kélen")
+      , (92, "bík̀ɔnɔntɔn ní fila")
+      , (93, "bík̀ɔnɔntɔn ní sàba")
+      , (94, "bík̀ɔnɔntɔn ní náani")
+      , (95, "bík̀ɔnɔntɔn ní dúuru")
+      , (96, "bík̀ɔnɔntɔn ní wɔɔrɔ")
+      , (97, "bík̀ɔnɔntɔn ní wólonwula")
+      , (98, "bík̀ɔnɔntɔn ní séegin")
+      , (99, "bík̀ɔnɔntɔn ní k̀ɔnɔntɔn")
+      , (100, "k̀ɛmɛ")
+      , (101, "k̀ɛmɛ ní kélen")
+      , (102, "k̀ɛmɛ ní fila")
+      , (103, "k̀ɛmɛ ní sàba")
+      , (104, "k̀ɛmɛ ní náani")
+      , (105, "k̀ɛmɛ ní dúuru")
+      , (106, "k̀ɛmɛ ní wɔɔrɔ")
+      , (107, "k̀ɛmɛ ní wólonwula")
+      , (108, "k̀ɛmɛ ní séegin")
+      , (109, "k̀ɛmɛ ní k̀ɔnɔntɔn")
+      , (110, "k̀ɛmɛ ní tán")
+      , (123, "k̀ɛmɛ ní mùgan ní sàba")
+      , (200, "k̀ɛmɛ fila")
+      , (300, "k̀ɛmɛ sàba")
+      , (321, "k̀ɛmɛ sàba ní mùgan ní kélen")
+      , (400, "k̀ɛmɛ náani")
+      , (500, "k̀ɛmɛ dúuru")
+      , (600, "k̀ɛmɛ wɔɔrɔ")
+      , (700, "wólonwula k̀ɛmɛ")
+      , (800, "séegin k̀ɛmɛ")
+      , (900, "k̀ɔnɔntɔn k̀ɛmɛ")
+      , (909, "k̀ɔnɔntɔn k̀ɛmɛ ní k̀ɔnɔntɔn")
+      , (990, "k̀ɔnɔntɔn k̀ɛmɛ ní bík̀ɔnɔntɔn")
+      , (999, "k̀ɔnɔntɔn k̀ɛmɛ ní bík̀ɔnɔntɔn ní k̀ɔnɔntɔn")
+      , (1000, "wa kélen")
+      , (1001, "wa kélen ní kélen")
+      , (1008, "wa kélen ní séegin")
+      , (1234, "wa kélen ní k̀ɛmɛ fila ní bísàba ní náani")
+      , (2000, "wa fila")
+      , (3000, "wa sàba")
+      , (4000, "wa náani")
+      , (4321, "wa náani ní k̀ɛmɛ sàba ní mùgan ní kélen")
+      , (5000, "wa dúuru")
+      , (6000, "wa wɔɔrɔ")
+      , (7000, "wólonwula wa")
+      , (8000, "séegin wa")
+      , (9000, "k̀ɔnɔntɔn wa")
+      , (10000, "tán wa")
+      , (12345, "tán ní wa fila ní k̀ɛmɛ sàba ní bínaani ní dúuru")
+      , (20000, "mùgan wa")
+      , (30000, "bíwa sàba")
+      , (40000, "bínaani wa")
+      , (50000, "bíwa dúuru")
+      , (54321, "bídúuru ní wa náani ní k̀ɛmɛ sàba ní mùgan ní kélen")
+      , (60000, "bíwa wɔɔrɔ")
+      , (70000, "bíwa wolonfila")
+      , (80000, "bíséegin wa")
+      , (90000, "bík̀ɔnɔntɔn wa")
+      , (100000, "k̀ɛmɛ wa")
+      , (123456, "k̀ɛmɛ ní mùgan ní wa sàba ní k̀ɛmɛ náani ní bídúuru ní wɔɔrɔ")
+      , (200000, "k̀ɛmɛ fila wa")
+      , (300000, "k̀ɛmɛ sàba wa")
+      , (400000, "k̀ɛmɛ náani wa")
+      , (500000, "k̀ɛmɛ dúuru wa")
+      , (600000, "k̀ɛmɛ wɔɔrɔ wa")
+      , (654321, "k̀ɛmɛ wɔɔrɔ ní bídúuru ní wa náani ní k̀ɛmɛ sàba ní mùgan ní kélen")
+      , (700000, "wólonwula k̀ɛmɛ wa")
+      , (800000, "séegin k̀ɛmɛ wa")
+      , (900000, "k̀ɔnɔntɔn k̀ɛmɛ wa")
+      , (1000000, "mílyɔn kélen")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/CA/TestData.hs b/src-test/Text/Numeral/Language/CA/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/CA/TestData.hs
@@ -0,0 +1,217 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        ca
+
+[@ISO639-2@]        cat
+
+[@ISO639-3@]        cat
+
+[@Native name@]     català
+
+[@English name@]    Catalan
+-}
+module Text.Numeral.Language.CA.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-catalan/en/cat/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "zero")
+      , (1, "un")
+      , (2, "dos")
+      , (3, "tres")
+      , (4, "quatre")
+      , (5, "cinc")
+      , (6, "sis")
+      , (7, "set")
+      , (8, "vuit")
+      , (9, "nou")
+      , (10, "deu")
+      , (11, "onze")
+      , (12, "dotze")
+      , (13, "tretze")
+      , (14, "catorze")
+      , (15, "quinze")
+      , (16, "setze")
+      , (17, "disset")
+      , (18, "divuit")
+      , (19, "dinou")
+      , (20, "vint")
+      , (21, "vint-i-u")
+      , (22, "vint-i-dos")
+      , (23, "vint-i-tres")
+      , (24, "vint-i-quatre")
+      , (25, "vint-i-cinc")
+      , (26, "vint-i-sis")
+      , (27, "vint-i-set")
+      , (28, "vint-i-vuit")
+      , (29, "vint-i-nou")
+      , (30, "trenta")
+      , (31, "trenta-u")
+      , (32, "trenta-dos")
+      , (33, "trenta-tres")
+      , (34, "trenta-quatre")
+      , (35, "trenta-cinc")
+      , (36, "trenta-sis")
+      , (37, "trenta-set")
+      , (38, "trenta-vuit")
+      , (39, "trenta-nou")
+      , (40, "quaranta")
+      , (41, "quaranta-u")
+      , (42, "quaranta-dos")
+      , (43, "quaranta-tres")
+      , (44, "quaranta-quatre")
+      , (45, "quaranta-cinc")
+      , (46, "quaranta-sis")
+      , (47, "quaranta-set")
+      , (48, "quaranta-vuit")
+      , (49, "quaranta-nou")
+      , (50, "cinquanta")
+      , (51, "cinquanta-u")
+      , (52, "cinquanta-dos")
+      , (53, "cinquanta-tres")
+      , (54, "cinquanta-quatre")
+      , (55, "cinquanta-cinc")
+      , (56, "cinquanta-sis")
+      , (57, "cinquanta-set")
+      , (58, "cinquanta-vuit")
+      , (59, "cinquanta-nou")
+      , (60, "seixanta")
+      , (61, "seixanta-u")
+      , (62, "seixanta-dos")
+      , (63, "seixanta-tres")
+      , (64, "seixanta-quatre")
+      , (65, "seixanta-cinc")
+      , (66, "seixanta-sis")
+      , (67, "seixanta-set")
+      , (68, "seixanta-vuit")
+      , (69, "seixanta-nou")
+      , (70, "setanta")
+      , (71, "setanta-u")
+      , (72, "setanta-dos")
+      , (73, "setanta-tres")
+      , (74, "setanta-quatre")
+      , (75, "setanta-cinc")
+      , (76, "setanta-sis")
+      , (77, "setanta-set")
+      , (78, "setanta-vuit")
+      , (79, "setanta-nou")
+      , (80, "vuitanta")
+      , (81, "vuitanta-u")
+      , (82, "vuitanta-dos")
+      , (83, "vuitanta-tres")
+      , (84, "vuitanta-quatre")
+      , (85, "vuitanta-cinc")
+      , (86, "vuitanta-sis")
+      , (87, "vuitanta-set")
+      , (88, "vuitanta-vuit")
+      , (89, "vuitanta-nou")
+      , (90, "noranta")
+      , (91, "noranta-u")
+      , (92, "noranta-dos")
+      , (93, "noranta-tres")
+      , (94, "noranta-quatre")
+      , (95, "noranta-cinc")
+      , (96, "noranta-sis")
+      , (97, "noranta-set")
+      , (98, "noranta-vuit")
+      , (99, "noranta-nou")
+      , (100, "cent")
+      , (101, "cent un")
+      , (102, "cent dos")
+      , (103, "cent tres")
+      , (104, "cent quatre")
+      , (105, "cent cinc")
+      , (106, "cent sis")
+      , (107, "cent set")
+      , (108, "cent vuit")
+      , (109, "cent nou")
+      , (110, "cent deu")
+      , (123, "cent vint-i-tres")
+      , (200, "dos-cents")
+      , (300, "tres-cents")
+      , (321, "tres-cents vint-i-u")
+      , (400, "quatre-cents")
+      , (500, "cinc-cents")
+      , (600, "sis-cents")
+      , (700, "set-cents")
+      , (800, "vuit-cents")
+      , (900, "nou-cents")
+      , (909, "nou-cents nou")
+      , (990, "nou-cents noranta")
+      , (999, "nou-cents noranta-nou")
+      , (1000, "mil")
+      , (1001, "mil un")
+      , (1008, "mil vuit")
+      , (1234, "mil dos-cents trenta-quatre")
+      , (2000, "dos mil")
+      , (3000, "tres mil")
+      , (4000, "quatre mil")
+      , (4321, "quatre mil tres-cents vint-i-u")
+      , (5000, "cinc mil")
+      , (6000, "sis mil")
+      , (7000, "set mil")
+      , (8000, "vuit mil")
+      , (9000, "nou mil")
+      , (10000, "deu mil")
+      , (12345, "dotze mil tres-cents quaranta-cinc")
+      , (20000, "vint mil")
+      , (30000, "trenta mil")
+      , (40000, "quaranta mil")
+      , (50000, "cinquanta mil")
+      , (54321, "cinquanta-quatre mil tres-cents vint-i-u")
+      , (60000, "seixanta mil")
+      , (70000, "setanta mil")
+      , (80000, "vuitanta mil")
+      , (90000, "noranta mil")
+      , (100000, "cent mil")
+      , (123456, "cent vint-i-tres mil quatre-cents cinquanta-sis")
+      , (200000, "dos-cents mil")
+      , (300000, "tres-cents mil")
+      , (400000, "quatre-cents mil")
+      , (500000, "cinc-cents mil")
+      , (600000, "sis-cents mil")
+      , (654321, "sis-cents cinquanta-quatre mil tres-cents vint-i-u")
+      , (700000, "set-cents mil")
+      , (800000, "vuit-cents mil")
+      , (900000, "nou-cents mil")
+      , (1000000, "un milió")
+      , (1234567, "un milió dos-cents trenta-quatre mil cinc-cents seixanta-set")
+      , (7654321, "set milions sis-cents cinquanta-quatre mil tres-cents vint-i-u")
+      , (1000000000, "mil milions")
+      , (1000000000000, "un bilió")
+      , (1000000000000000000, "un trilió")
+      , (1000000000000000000000, "un triliard")
+      , (1000000000000000000000000, "un quadrilió")
+      , (1000000000000000000000000000, "un quadriliard")
+      , (1000000000000000000000000000000, "un quintilió")
+      , (1000000000000000000000000000000000, "un quintiliard")
+      , (1000000000000000000000000000000000000, "un sextilió")
+      , (1000000000000000000000000000000000000000, "un sextiliard")
+      , (1000000000000000000000000000000000000000000, "un septilió")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/CAF/TestData.hs b/src-test/Text/Numeral/Language/CAF/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/CAF/TestData.hs
@@ -0,0 +1,256 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        caf
+
+[@Native name@]     Dakeł (ᑕᗸᒡ)
+
+[@English name@]    Southern Carrier
+-}
+module Text.Numeral.Language.CAF.TestData
+  ( cardinals
+  , syllabic_cardinals
+  ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-carrier/en/caf/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "lhuk’i")
+      , (2, "nankoh")
+      , (3, "tak’ih")
+      , (4, "dink’ih")
+      , (5, "skwunlai")
+      , (6, "lhk’uttak’ih")
+      , (7, "lhtak’alt’i")
+      , (8, "lhk’utdink’ih")
+      , (9, "lhuk’i hooloh")
+      , (10, "lanezyi")
+      , (11, "lanezyi ’o’un lhuk’i")
+      , (12, "lanezyi ’o’un nankoh")
+      , (13, "lanezyi ’o’un tak’ih")
+      , (14, "lanezyi ’o’un dink’ih")
+      , (15, "lanezyi ’o’un skwunlai")
+      , (16, "lanezyi ’o’un lhk’uttak’ih")
+      , (17, "lanezyi ’o’un lhtak’alt’i")
+      , (18, "lanezyi ’o’un lhk’utdink’ih")
+      , (19, "lanezyi ’o’un lhuk’i hooloh")
+      , (20, "nat lanezyi")
+      , (21, "nat lanezyi ’o’un lhuk’i")
+      , (22, "nat lanezyi ’o’un nankoh")
+      , (23, "nat lanezyi ’o’un tak’ih")
+      , (24, "nat lanezyi ’o’un dink’ih")
+      , (25, "nat lanezyi ’o’un skwunlai")
+      , (26, "nat lanezyi ’o’un lhk’uttak’ih")
+      , (27, "nat lanezyi ’o’un lhtak’alt’i")
+      , (28, "nat lanezyi ’o’un lhk’utdink’ih")
+      , (29, "nat lanezyi ’o’un lhuk’i hooloh")
+      , (30, "tat lanezyi")
+      , (31, "tat lanezyi ’o’un lhuk’i")
+      , (32, "tat lanezyi ’o’un nankoh")
+      , (33, "tat lanezyi ’o’un tak’ih")
+      , (34, "tat lanezyi ’o’un dink’ih")
+      , (35, "tat lanezyi ’o’un skwunlai")
+      , (36, "tat lanezyi ’o’un lhk’uttak’ih")
+      , (37, "tat lanezyi ’o’un lhtak’alt’i")
+      , (38, "tat lanezyi ’o’un lhk’utdink’ih")
+      , (39, "tat lanezyi ’o’un lhuk’i hooloh")
+      , (40, "dit lanezyi")
+      , (41, "dit lanezyi ’o’un lhuk’i")
+      , (42, "dit lanezyi ’o’un nankoh")
+      , (43, "dit lanezyi ’o’un tak’ih")
+      , (44, "dit lanezyi ’o’un dink’ih")
+      , (45, "dit lanezyi ’o’un skwunlai")
+      , (46, "dit lanezyi ’o’un lhk’uttak’ih")
+      , (47, "dit lanezyi ’o’un lhtak’alt’i")
+      , (48, "dit lanezyi ’o’un lhk’utdink’ih")
+      , (49, "dit lanezyi ’o’un lhuk’i hooloh")
+      , (50, "skwunlat lanezyi")
+      , (51, "skwunlat lanezyi ’o’un lhuk’i")
+      , (52, "skwunlat lanezyi ’o’un nankoh")
+      , (53, "skwunlat lanezyi ’o’un tak’ih")
+      , (54, "skwunlat lanezyi ’o’un dink’ih")
+      , (55, "skwunlat lanezyi ’o’un skwunlai")
+      , (56, "skwunlat lanezyi ’o’un lhk’uttak’ih")
+      , (57, "skwunlat lanezyi ’o’un lhtak’alt’i")
+      , (58, "skwunlat lanezyi ’o’un lhk’utdink’ih")
+      , (59, "skwunlat lanezyi ’o’un lhuk’i hooloh")
+      , (60, "lhk’utat lanezyi")
+      , (61, "lhk’utat lanezyi ’o’un lhuk’i")
+      , (62, "lhk’utat lanezyi ’o’un nankoh")
+      , (63, "lhk’utat lanezyi ’o’un tak’ih")
+      , (64, "lhk’utat lanezyi ’o’un dink’ih")
+      , (65, "lhk’utat lanezyi ’o’un skwunlai")
+      , (66, "lhk’utat lanezyi ’o’un lhk’uttak’ih")
+      , (67, "lhk’utat lanezyi ’o’un lhtak’alt’i")
+      , (68, "lhk’utat lanezyi ’o’un lhk’utdink’ih")
+      , (69, "lhk’utat lanezyi ’o’un lhuk’i hooloh")
+      , (70, "lhtak’alt’it lanezyi")
+      , (71, "lhtak’alt’it lanezyi ’o’un lhuk’i")
+      , (72, "lhtak’alt’it lanezyi ’o’un nankoh")
+      , (73, "lhtak’alt’it lanezyi ’o’un tak’ih")
+      , (74, "lhtak’alt’it lanezyi ’o’un dink’ih")
+      , (75, "lhtak’alt’it lanezyi ’o’un skwunlai")
+      , (76, "lhtak’alt’it lanezyi ’o’un lhk’uttak’ih")
+      , (77, "lhtak’alt’it lanezyi ’o’un lhtak’alt’i")
+      , (78, "lhtak’alt’it lanezyi ’o’un lhk’utdink’ih")
+      , (79, "lhtak’alt’it lanezyi ’o’un lhuk’i hooloh")
+      , (80, "lhk’udit lanezyi")
+      , (81, "lhk’udit lanezyi ’o’un lhuk’i")
+      , (82, "lhk’udit lanezyi ’o’un nankoh")
+      , (83, "lhk’udit lanezyi ’o’un tak’ih")
+      , (84, "lhk’udit lanezyi ’o’un dink’ih")
+      , (85, "lhk’udit lanezyi ’o’un skwunlai")
+      , (86, "lhk’udit lanezyi ’o’un lhk’uttak’ih")
+      , (87, "lhk’udit lanezyi ’o’un lhtak’alt’i")
+      , (88, "lhk’udit lanezyi ’o’un lhk’utdink’ih")
+      , (89, "lhk’udit lanezyi ’o’un lhuk’i hooloh")
+      , (90, "lhuk’i hooloh lanezyi")
+      , (91, "lhuk’i hooloh lanezyi ’o’un lhuk’i")
+      , (92, "lhuk’i hooloh lanezyi ’o’un nankoh")
+      , (93, "lhuk’i hooloh lanezyi ’o’un tak’ih")
+      , (94, "lhuk’i hooloh lanezyi ’o’un dink’ih")
+      , (95, "lhuk’i hooloh lanezyi ’o’un skwunlai")
+      , (96, "lhuk’i hooloh lanezyi ’o’un lhk’uttak’ih")
+      , (97, "lhuk’i hooloh lanezyi ’o’un lhtak’alt’i")
+      , (98, "lhuk’i hooloh lanezyi ’o’un lhk’utdink’ih")
+      , (99, "lhuk’i hooloh lanezyi ’o’un lhuk’i hooloh")
+      , (100, "lhk’ut’lanezyi")
+      ]
+    )
+  ]
+
+-- Using Carrier sylllabics
+syllabic_cardinals ∷ (Num i) ⇒ TestData i
+syllabic_cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "ᘰᗿ")
+      , (2, "ᘇᐣᗶᑋ")
+      , (3, "ᗡᗿᑋ")
+      , (4, "ᑔᐣᗿᑋ")
+      , (5, "ᔆᐠᗒᐣᘧᐉ")
+      , (6, "ᒡᗽᐪᗡᗿᑋ")
+      , (7, "ᒡᗡᘀᑊᗦ")
+      , (8, "ᒡᗽᐪᑔᐣᗿᑋ")
+      , (9, "ᘰᗿ ᐯᘣᑋ")
+      , (10, "ᘧᘅᙆᘒ")
+      , (11, "ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ")
+      , (12, "ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘇᐣᗶᑋ")
+      , (13, "ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᗡᗿᑋ")
+      , (14, "ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᑔᐣᗿᑋ")
+      , (15, "ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᔆᐠᗒᐣᘧᐉ")
+      , (16, "ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᗡᗿᑋ")
+      , (17, "ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗡᘀᑊᗦ")
+      , (18, "ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᑔᐣᗿᑋ")
+      , (19, "ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ ᐯᘣᑋ")
+      , (20, "ᘇᐪ ᘧᘅᙆᘒ")
+      , (21, "ᘇᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ")
+      , (22, "ᘇᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘇᐣᗶᑋ")
+      , (23, "ᘇᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᗡᗿᑋ")
+      , (24, "ᘇᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᑔᐣᗿᑋ")
+      , (25, "ᘇᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᔆᐠᗒᐣᘧᐉ")
+      , (26, "ᘇᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᗡᗿᑋ")
+      , (27, "ᘇᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗡᘀᑊᗦ")
+      , (28, "ᘇᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᑔᐣᗿᑋ")
+      , (29, "ᘇᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ ᐯᘣᑋ")
+      , (30, "ᗡᐪ ᘧᘅᙆᘒ")
+      , (31, "ᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ")
+      , (32, "ᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘇᐣᗶᑋ")
+      , (33, "ᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᗡᗿᑋ")
+      , (34, "ᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᑔᐣᗿᑋ")
+      , (35, "ᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᔆᐠᗒᐣᘧᐉ")
+      , (36, "ᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᗡᗿᑋ")
+      , (37, "ᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗡᘀᑊᗦ")
+      , (38, "ᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᑔᐣᗿᑋ")
+      , (39, "ᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ ᐯᘣᑋ")
+      , (40, "ᑔᐪ ᘧᘅᙆᘒ")
+      , (41, "ᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ")
+      , (42, "ᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘇᐣᗶᑋ")
+      , (43, "ᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᗡᗿᑋ")
+      , (44, "ᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᑔᐣᗿᑋ")
+      , (45, "ᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᔆᐠᗒᐣᘧᐉ")
+      , (46, "ᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᗡᗿᑋ")
+      , (47, "ᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗡᘀᑊᗦ")
+      , (48, "ᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᑔᐣᗿᑋ")
+      , (49, "ᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ ᐯᘣᑋ")
+      , (50, "ᔆᐠᗒᐣᘧᐪ ᘧᘅᙆᘒ")
+      , (51, "ᔆᐠᗒᐣᘧᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ")
+      , (52, "ᔆᐠᗒᐣᘧᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘇᐣᗶᑋ")
+      , (53, "ᔆᐠᗒᐣᘧᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᗡᗿᑋ")
+      , (54, "ᔆᐠᗒᐣᘧᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᑔᐣᗿᑋ")
+      , (55, "ᔆᐠᗒᐣᘧᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᔆᐠᗒᐣᘧᐉ")
+      , (56, "ᔆᐠᗒᐣᘧᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᗡᗿᑋ")
+      , (57, "ᔆᐠᗒᐣᘧᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗡᘀᑊᗦ")
+      , (58, "ᔆᐠᗒᐣᘧᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᑔᐣᗿᑋ")
+      , (59, "ᔆᐠᗒᐣᘧᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ ᐯᘣᑋ")
+      , (60, "ᒡᗽᗡᐪ ᘧᘅᙆᘒ")
+      , (61, "ᒡᗽᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ")
+      , (62, "ᒡᗽᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘇᐣᗶᑋ")
+      , (63, "ᒡᗽᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᗡᗿᑋ")
+      , (64, "ᒡᗽᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᑔᐣᗿᑋ")
+      , (65, "ᒡᗽᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᔆᐠᗒᐣᘧᐉ")
+      , (66, "ᒡᗽᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᗡᗿᑋ")
+      , (67, "ᒡᗽᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗡᘀᑊᗦ")
+      , (68, "ᒡᗽᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᑔᐣᗿᑋ")
+      , (69, "ᒡᗽᗡᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ ᐯᘣᑋ")
+      , (70, "ᒡᗡᘀᑊᗦᐪ ᘧᘅᙆᘒ")
+      , (71, "ᒡᗡᘀᑊᗦᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ")
+      , (72, "ᒡᗡᘀᑊᗦᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘇᐣᗶᑋ")
+      , (73, "ᒡᗡᘀᑊᗦᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᗡᗿᑋ")
+      , (74, "ᒡᗡᘀᑊᗦᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᑔᐣᗿᑋ")
+      , (75, "ᒡᗡᘀᑊᗦᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᔆᐠᗒᐣᘧᐉ")
+      , (76, "ᒡᗡᘀᑊᗦᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᗡᗿᑋ")
+      , (77, "ᒡᗡᘀᑊᗦᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗡᘀᑊᗦ")
+      , (78, "ᒡᗡᘀᑊᗦᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᑔᐣᗿᑋ")
+      , (79, "ᒡᗡᘀᑊᗦᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ ᐯᘣᑋ")
+      , (80, "ᒡᗽᑔᐪ ᘧᘅᙆᘒ")
+      , (81, "ᒡᗽᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ")
+      , (82, "ᒡᗽᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘇᐣᗶᑋ")
+      , (83, "ᒡᗽᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᗡᗿᑋ")
+      , (84, "ᒡᗽᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᑔᐣᗿᑋ")
+      , (85, "ᒡᗽᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᔆᐠᗒᐣᘧᐉ")
+      , (86, "ᒡᗽᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᗡᗿᑋ")
+      , (87, "ᒡᗽᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗡᘀᑊᗦ")
+      , (88, "ᒡᗽᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᑔᐣᗿᑋ")
+      , (89, "ᒡᗽᑔᐪ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ ᐯᘣᑋ")
+      , (90, "ᘰᗿ ᐯᘣᑋ ᘧᘅᙆᘒ")
+      , (91, "ᘰᗿ ᐯᘣᑋ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ")
+      , (92, "ᘰᗿ ᐯᘣᑋ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘇᐣᗶᑋ")
+      , (93, "ᘰᗿ ᐯᘣᑋ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᗡᗿᑋ")
+      , (94, "ᘰᗿ ᐯᘣᑋ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᑔᐣᗿᑋ")
+      , (95, "ᘰᗿ ᐯᘣᑋ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᔆᐠᗒᐣᘧᐉ")
+      , (96, "ᘰᗿ ᐯᘣᑋ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᗡᗿᑋ")
+      , (97, "ᘰᗿ ᐯᘣᑋ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗡᘀᑊᗦ")
+      , (98, "ᘰᗿ ᐯᘣᑋ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᒡᗽᐪᑔᐣᗿᑋ")
+      , (99, "ᘰᗿ ᐯᘣᑋ ᘧᘅᙆᘒ ᐧᐃᐧᐅᐣ ᘰᗿ ᐯᘣᑋ")
+      , (100, "ᒡᗽᐪᐧᘧᘅᙆᘒ")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/CBK/TestData.hs b/src-test/Text/Numeral/Language/CBK/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/CBK/TestData.hs
@@ -0,0 +1,215 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        cbk
+
+[@Native name@]     Chabacano
+
+[@English name@]    Chavacano
+-}
+module Text.Numeral.Language.CBK.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-chavacano/en/cbk/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "cero")
+      , (1, "uno")
+      , (2, "dos")
+      , (3, "tres")
+      , (4, "cuatro")
+      , (5, "cinco")
+      , (6, "seis")
+      , (7, "siete")
+      , (8, "ocho")
+      , (9, "nueve")
+      , (10, "diez")
+      , (11, "once")
+      , (12, "doce")
+      , (13, "trece")
+      , (14, "catorce")
+      , (15, "quince")
+      , (16, "dieciséis")
+      , (17, "diecisiete")
+      , (18, "dieciocho")
+      , (19, "diecinueve")
+      , (20, "veinte")
+      , (21, "veintiún")
+      , (22, "veintidós")
+      , (23, "veintitrés")
+      , (24, "veinticuatro")
+      , (25, "veinticinco")
+      , (26, "veintiséis")
+      , (27, "veintisiete")
+      , (28, "veintiocho")
+      , (29, "veintinueve")
+      , (30, "treinta")
+      , (31, "treinta y uno")
+      , (32, "treinta y dos")
+      , (33, "treinta y tres")
+      , (34, "treinta y cuatro")
+      , (35, "treinta y cinco")
+      , (36, "treinta y seis")
+      , (37, "treinta y siete")
+      , (38, "treinta y ocho")
+      , (39, "treinta y nueve")
+      , (40, "cuarenta")
+      , (41, "cuarenta y uno")
+      , (42, "cuarenta y dos")
+      , (43, "cuarenta y tres")
+      , (44, "cuarenta y cuatro")
+      , (45, "cuarenta y cinco")
+      , (46, "cuarenta y seis")
+      , (47, "cuarenta y siete")
+      , (48, "cuarenta y ocho")
+      , (49, "cuarenta y nueve")
+      , (50, "cinquenta")
+      , (51, "cinquenta y uno")
+      , (52, "cinquenta y dos")
+      , (53, "cinquenta y tres")
+      , (54, "cinquenta y cuatro")
+      , (55, "cinquenta y cinco")
+      , (56, "cinquenta y seis")
+      , (57, "cinquenta y siete")
+      , (58, "cinquenta y ocho")
+      , (59, "cinquenta y nueve")
+      , (60, "sesenta")
+      , (61, "sesenta y uno")
+      , (62, "sesenta y dos")
+      , (63, "sesenta y tres")
+      , (64, "sesenta y cuatro")
+      , (65, "sesenta y cinco")
+      , (66, "sesenta y seis")
+      , (67, "sesenta y siete")
+      , (68, "sesenta y ocho")
+      , (69, "sesenta y nueve")
+      , (70, "setenta")
+      , (71, "setenta y uno")
+      , (72, "setenta y dos")
+      , (73, "setenta y tres")
+      , (74, "setenta y cuatro")
+      , (75, "setenta y cinco")
+      , (76, "setenta y seis")
+      , (77, "setenta y siete")
+      , (78, "setenta y ocho")
+      , (79, "setenta y nueve")
+      , (80, "ochenta")
+      , (81, "ochenta y uno")
+      , (82, "ochenta y dos")
+      , (83, "ochenta y tres")
+      , (84, "ochenta y cuatro")
+      , (85, "ochenta y cinco")
+      , (86, "ochenta y seis")
+      , (87, "ochenta y siete")
+      , (88, "ochenta y ocho")
+      , (89, "ochenta y nueve")
+      , (90, "noventa")
+      , (91, "noventa y uno")
+      , (92, "noventa y dos")
+      , (93, "noventa y tres")
+      , (94, "noventa y cuatro")
+      , (95, "noventa y cinco")
+      , (96, "noventa y seis")
+      , (97, "noventa y siete")
+      , (98, "noventa y ocho")
+      , (99, "noventa y nueve")
+      , (100, "ciento")
+      , (101, "ciento uno")
+      , (102, "ciento dos")
+      , (103, "ciento tres")
+      , (104, "ciento cuatro")
+      , (105, "ciento cinco")
+      , (106, "ciento seis")
+      , (107, "ciento siete")
+      , (108, "ciento ocho")
+      , (109, "ciento nueve")
+      , (110, "ciento diez")
+      , (123, "ciento veintitrés")
+      , (200, "dos cientos")
+      , (300, "tres cientos")
+      , (321, "tres cientos veintiún")
+      , (400, "cuatro cientos")
+      , (500, "quinientos")
+      , (600, "seis cientos")
+      , (700, "siete cientos")
+      , (800, "ocho cientos")
+      , (900, "nueve cientos")
+      , (909, "nueve cientos nueve")
+      , (990, "nueve cientos noventa")
+      , (999, "nueve cientos noventa y nueve")
+      , (1000, "un mil")
+      , (1001, "un mil uno")
+      , (1008, "un mil ocho")
+      , (1234, "un mil dos cientos treinta y cuatro")
+      , (2000, "dos mil")
+      , (3000, "tres mil")
+      , (4000, "cuatro mil")
+      , (4321, "cuatro mil tres cientos veintiún")
+      , (5000, "cinco mil")
+      , (6000, "seis mil")
+      , (7000, "siete mil")
+      , (8000, "ocho mil")
+      , (9000, "nueve mil")
+      , (10000, "diez mil")
+      , (12345, "doce mil tres cientos cuarenta y cinco")
+      , (20000, "veinte mil")
+      , (30000, "treinta mil")
+      , (40000, "cuarenta mil")
+      , (50000, "cinquenta mil")
+      , (54321, "cinquenta y cuatro mil tres cientos veintiún")
+      , (60000, "sesenta mil")
+      , (70000, "setenta mil")
+      , (80000, "ochenta mil")
+      , (90000, "noventa mil")
+      , (100000, "ciento mil")
+      , (123456, "ciento veintitrés mil cuatro cientos cinquenta y seis")
+      , (200000, "dos cientos mil")
+      , (300000, "tres cientos mil")
+      , (400000, "cuatro cientos mil")
+      , (500000, "quinientos mil")
+      , (600000, "seis cientos mil")
+      , (654321, "seis cientos cinquenta y cuatro mil tres cientos veintiún")
+      , (700000, "siete cientos mil")
+      , (800000, "ocho cientos mil")
+      , (900000, "nueve cientos mil")
+      , (1000000, "un millón")
+      , (1234567, "un millón dos cientos treinta y cuatro mil quinientos sesenta y siete")
+      , (7654321, "siete millones seis cientos cinquenta y cuatro mil tres cientos veintiún")
+      , (1000000000, "un billón")
+      , (1000000000000, "un trillón")
+      , (1000000000000000, "un cuatrillón")
+      , (1000000000000000000, "un quintillón")
+      , (1000000000000000000000, "un sextillón")
+      , (1000000000000000000000000, "un septillón")
+      , (1000000000000000000000000000, "un octillón")
+      , (1000000000000000000000000000000, "un nonillón")
+      , (1000000000000000000000000000000000, "un decallón")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/CHN/TestData.hs b/src-test/Text/Numeral/Language/CHN/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/CHN/TestData.hs
@@ -0,0 +1,140 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2B@]       chn
+
+[@ISO639-3@]        chn
+
+[@Native name@]     -
+
+[@English name@]    Chinook Jargon
+-}
+
+module Text.Numeral.Language.CHN.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "ikt")
+      , (2, "mokst")
+      , (3, "klone")
+      , (4, "lakit")
+      , (5, "kwinnum")
+      , (6, "taghum")
+      , (7, "sinamokst")
+      , (8, "stotekin")
+      , (9, "kwaist")
+      , (10, "tahtlum")
+      , (11, "tahtlum pe ikt")
+      , (12, "tahtlum pe mokst")
+      , (13, "tahtlum pe klone")
+      , (14, "tahtlum pe lakit")
+      , (15, "tahtlum pe kwinnum")
+      , (16, "tahtlum pe taghum")
+      , (17, "tahtlum pe sinamokst")
+      , (18, "tahtlum pe stotekin")
+      , (19, "tahtlum pe kwaist")
+      , (20, "mokst tahtlum")
+      , (21, "mokst tahtlum pe ikt")
+      , (22, "mokst tahtlum pe mokst")
+      , (23, "mokst tahtlum pe klone")
+      , (24, "mokst tahtlum pe lakit")
+      , (25, "mokst tahtlum pe kwinnum")
+      , (26, "mokst tahtlum pe taghum")
+      , (27, "mokst tahtlum pe sinamokst")
+      , (28, "mokst tahtlum pe stotekin")
+      , (29, "mokst tahtlum pe kwaist")
+      , (30, "klone tahtlum")
+      , (31, "klone tahtlum pe ikt")
+      , (32, "klone tahtlum pe mokst")
+      , (33, "klone tahtlum pe klone")
+      , (34, "klone tahtlum pe lakit")
+      , (35, "klone tahtlum pe kwinnum")
+      , (36, "klone tahtlum pe taghum")
+      , (37, "klone tahtlum pe sinamokst")
+      , (38, "klone tahtlum pe stotekin")
+      , (39, "klone tahtlum pe kwaist")
+      , (40, "lakit tahtlum")
+      , (41, "lakit tahtlum pe ikt")
+      , (42, "lakit tahtlum pe mokst")
+      , (43, "lakit tahtlum pe klone")
+      , (44, "lakit tahtlum pe lakit")
+      , (45, "lakit tahtlum pe kwinnum")
+      , (46, "lakit tahtlum pe taghum")
+      , (47, "lakit tahtlum pe sinamokst")
+      , (48, "lakit tahtlum pe stotekin")
+      , (49, "lakit tahtlum pe kwaist")
+      , (50, "kwinnum tahtlum")
+      , (51, "kwinnum tahtlum pe ikt")
+      , (52, "kwinnum tahtlum pe mokst")
+      , (53, "kwinnum tahtlum pe klone")
+      , (54, "kwinnum tahtlum pe lakit")
+      , (55, "kwinnum tahtlum pe kwinnum")
+      , (56, "kwinnum tahtlum pe taghum")
+      , (57, "kwinnum tahtlum pe sinamokst")
+      , (58, "kwinnum tahtlum pe stotekin")
+      , (59, "kwinnum tahtlum pe kwaist")
+      , (60, "taghum tahtlum")
+      , (61, "taghum tahtlum pe ikt")
+      , (62, "taghum tahtlum pe mokst")
+      , (63, "taghum tahtlum pe klone")
+      , (64, "taghum tahtlum pe lakit")
+      , (65, "taghum tahtlum pe kwinnum")
+      , (66, "taghum tahtlum pe taghum")
+      , (67, "taghum tahtlum pe sinamokst")
+      , (68, "taghum tahtlum pe stotekin")
+      , (69, "taghum tahtlum pe kwaist")
+      , (70, "sinamokst tahtlum")
+      , (71, "sinamokst tahtlum pe ikt")
+      , (72, "sinamokst tahtlum pe mokst")
+      , (73, "sinamokst tahtlum pe klone")
+      , (74, "sinamokst tahtlum pe lakit")
+      , (75, "sinamokst tahtlum pe kwinnum")
+      , (76, "sinamokst tahtlum pe taghum")
+      , (77, "sinamokst tahtlum pe sinamokst")
+      , (78, "sinamokst tahtlum pe stotekin")
+      , (79, "sinamokst tahtlum pe kwaist")
+      , (80, "stotekin tahtlum")
+      , (81, "stotekin tahtlum pe ikt")
+      , (82, "stotekin tahtlum pe mokst")
+      , (83, "stotekin tahtlum pe klone")
+      , (84, "stotekin tahtlum pe lakit")
+      , (85, "stotekin tahtlum pe kwinnum")
+      , (86, "stotekin tahtlum pe taghum")
+      , (87, "stotekin tahtlum pe sinamokst")
+      , (88, "stotekin tahtlum pe stotekin")
+      , (89, "stotekin tahtlum pe kwaist")
+      , (90, "kwaist tahtlum")
+      , (91, "kwaist tahtlum pe ikt")
+      , (92, "kwaist tahtlum pe mokst")
+      , (93, "kwaist tahtlum pe klone")
+      , (94, "kwaist tahtlum pe lakit")
+      , (95, "kwaist tahtlum pe kwinnum")
+      , (96, "kwaist tahtlum pe taghum")
+      , (97, "kwaist tahtlum pe sinamokst")
+      , (98, "kwaist tahtlum pe stotekin")
+      , (99, "kwaist tahtlum pe kwaist")
+      , (100, "tukamonuk")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/CHR/TestData.hs b/src-test/Text/Numeral/Language/CHR/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/CHR/TestData.hs
@@ -0,0 +1,190 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        chr
+
+[@ISO639-3@]        chr
+
+[@Native name@]     ᏣᎳᎩ ᎦᏬᏂᎯᏍᏗ (Tsalagi Gawonihisdi)
+
+[@English name@]    Cherokee
+-}
+module Text.Numeral.Language.CHR.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://en.wikipedia.org/wiki/Cherokee_language
+  http://www.languagesandnumbers.com/how-to-count-in-cherokee/en/chr/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "Ꮭ ᎪᏍᏗ")
+      , (1, "ᏐᏬ")
+      , (2, "ᏔᎵ")
+      , (3, "ᏦᎢ")
+      , (4, "ᏅᎩ")
+      , (5, "ᎯᏍᎩ")
+      , (6, "ᏑᏓᎵ")
+      , (7, "ᎦᎵᏉᎩ")
+      , (8, "ᏧᏁᎳ")
+      , (9, "ᏐᏁᎳ")
+      , (10, "ᏍᎪᎯ")
+      , (11, "ᏌᏚ")
+      , (12, "ᏔᎵᏚ")
+      , (13, "ᏦᎦᏚ")
+      , (14, "ᏂᎦᏚ")
+      , (15, "ᎯᏍᎦᏚ")
+      , (16, "ᏓᎳᏚ")
+      , (17, "ᎦᎵᏆᏚ")
+      , (18, "ᏁᎳᏚ")
+      , (19, "ᏐᏁᎳᏚ")
+      , (20, "ᏔᎵᏍᎪᎯ")
+      , (21, "ᏔᎵᏍᎪ ᏌᏬ")
+      , (22, "ᏔᎵᏍᎪ ᏔᎵ")
+      , (23, "ᏔᎵᏍᎪ ᏦᎢ")
+      , (24, "ᏔᎵᏍᎪ ᏅᎩ")
+      , (25, "ᏔᎵᏍᎪ ᎯᏍᎩ")
+      , (26, "ᏔᎵᏍᎪ ᏑᏓᎵ")
+      , (27, "ᏔᎵᏍᎪ ᎦᎵᏉᎩ")
+      , (28, "ᏔᎵᏍᎪ ᏧᏁᎳ")
+      , (29, "ᏔᎵᏍᎪ ᏐᏁᎳ")
+      , (30, "ᏦᎢᏍᎪᎯ")
+      , (31, "ᏦᎢᏍᎪ ᏌᏬ")
+      , (32, "ᏦᎢᏍᎪ ᏔᎵ")
+      , (33, "ᏦᎢᏍᎪ ᏦᎢ")
+      , (34, "ᏦᎢᏍᎪ ᏅᎩ")
+      , (35, "ᏦᎢᏍᎪ ᎯᏍᎩ")
+      , (36, "ᏦᎢᏍᎪ ᏑᏓᎵ")
+      , (37, "ᏦᎢᏍᎪ ᎦᎵᏉᎩ")
+      , (38, "ᏦᎢᏍᎪ ᏧᏁᎳ")
+      , (39, "ᏦᎢᏍᎪ ᏐᏁᎳ")
+      , (40, "ᏅᎩᏍᎪᎯ")
+      , (41, "ᏅᎩᏍᎪ ᏌᏬ")
+      , (42, "ᏅᎩᏍᎪ ᏔᎵ")
+      , (43, "ᏅᎩᏍᎪ ᏦᎢ")
+      , (44, "ᏅᎩᏍᎪ ᏅᎩ")
+      , (45, "ᏅᎩᏍᎪ ᎯᏍᎩ")
+      , (46, "ᏅᎩᏍᎪ ᏑᏓᎵ")
+      , (47, "ᏅᎩᏍᎪ ᎦᎵᏉᎩ")
+      , (48, "ᏅᎩᏍᎪ ᏧᏁᎳ")
+      , (49, "ᏅᎩᏍᎪ ᏐᏁᎳ")
+      , (50, "ᎯᏍᎩᏍᎪᎯ")
+      , (51, "ᎯᏍᎩᏍᎪ ᏌᏬ")
+      , (52, "ᎯᏍᎩᏍᎪ ᏔᎵ")
+      , (53, "ᎯᏍᎩᏍᎪ ᏦᎢ")
+      , (54, "ᎯᏍᎩᏍᎪ ᏅᎩ")
+      , (55, "ᎯᏍᎩᏍᎪ ᎯᏍᎩ")
+      , (56, "ᎯᏍᎩᏍᎪ ᏑᏓᎵ")
+      , (57, "ᎯᏍᎩᏍᎪ ᎦᎵᏉᎩ")
+      , (58, "ᎯᏍᎩᏍᎪ ᏧᏁᎳ")
+      , (59, "ᎯᏍᎩᏍᎪ ᏐᏁᎳ")
+      , (60, "ᏑᏓᎵᏍᎪᎯ")
+      , (61, "ᏑᏓᎵᏍᎪ ᏌᏬ")
+      , (62, "ᏑᏓᎵᏍᎪ ᏔᎵ")
+      , (63, "ᏑᏓᎵᏍᎪ ᏦᎢ")
+      , (64, "ᏑᏓᎵᏍᎪ ᏅᎩ")
+      , (65, "ᏑᏓᎵᏍᎪ ᎯᏍᎩ")
+      , (66, "ᏑᏓᎵᏍᎪ ᏑᏓᎵ")
+      , (67, "ᏑᏓᎵᏍᎪ ᎦᎵᏉᎩ")
+      , (68, "ᏑᏓᎵᏍᎪ ᏧᏁᎳ")
+      , (69, "ᏑᏓᎵᏍᎪ ᏐᏁᎳ")
+      , (70, "ᎦᎵᏆᏍᎪᎯ")
+      , (71, "ᎦᎵᏆᏍᎪ ᏌᏬ")
+      , (72, "ᎦᎵᏆᏍᎪ ᏔᎵ")
+      , (73, "ᎦᎵᏆᏍᎪ ᏦᎢ")
+      , (74, "ᎦᎵᏆᏍᎪ ᏅᎩ")
+      , (75, "ᎦᎵᏆᏍᎪ ᎯᏍᎩ")
+      , (76, "ᎦᎵᏆᏍᎪ ᏑᏓᎵ")
+      , (77, "ᎦᎵᏆᏍᎪ ᎦᎵᏉᎩ")
+      , (78, "ᎦᎵᏆᏍᎪ ᏧᏁᎳ")
+      , (79, "ᎦᎵᏆᏍᎪ ᏐᏁᎳ")
+      , (80, "ᏧᏁᎳᏍᎪᎯ")
+      , (81, "ᏧᏁᎳᏍᎪ ᏌᏬ")
+      , (82, "ᏧᏁᎳᏍᎪ ᏔᎵ")
+      , (83, "ᏧᏁᎳᏍᎪ ᏦᎢ")
+      , (84, "ᏧᏁᎳᏍᎪ ᏅᎩ")
+      , (85, "ᏧᏁᎳᏍᎪ ᎯᏍᎩ")
+      , (86, "ᏧᏁᎳᏍᎪ ᏑᏓᎵ")
+      , (87, "ᏧᏁᎳᏍᎪ ᎦᎵᏉᎩ")
+      , (88, "ᏧᏁᎳᏍᎪ ᏧᏁᎳ")
+      , (89, "ᏧᏁᎳᏍᎪ ᏐᏁᎳ")
+      , (90, "ᏐᏁᎳᏍᎪᎯ")
+      , (91, "ᏐᏁᎳᏍᎪ ᏌᏬ")
+      , (92, "ᏐᏁᎳᏍᎪ ᏔᎵ")
+      , (93, "ᏐᏁᎳᏍᎪ ᏦᎢ")
+      , (94, "ᏐᏁᎳᏍᎪ ᏅᎩ")
+      , (95, "ᏐᏁᎳᏍᎪ ᎯᏍᎩ")
+      , (96, "ᏐᏁᎳᏍᎪ ᏑᏓᎵ")
+      , (97, "ᏐᏁᎳᏍᎪ ᎦᎵᏉᎩ")
+      , (98, "ᏐᏁᎳᏍᎪ ᏧᏁᎳ")
+      , (99, "ᏐᏁᎳᏍᎪ ᏐᏁᎳ")
+      , (100, "ᏍᎪᎯᏥᏆ")
+      , (101, "ᏐᏬ ᏍᎪᎯᏥᏆ ᏌᏬ")
+      , (102, "ᏐᏬ ᏍᎪᎯᏥᏆ ᏔᎵ")
+      , (110, "ᏐᏬ ᏍᎪᎯᏥᏆ ᏍᎪᎯ")
+      , (111, "ᏐᏬ ᏍᎪᎯᏥᏆ ᏌᏚ")
+      , (112, "ᏐᏬ ᏍᎪᎯᏥᏆ ᏔᎵᏚ")
+      , (123, "ᏐᏬ ᏍᎪᎯᏥᏆ ᏔᎵᏍᎪ ᏦᎢ")
+      , (200, "ᏔᎵᏍᎪᎯᏥᏆ")
+      , (234, "ᏔᎵ ᏍᎪᎯᏥᏆ ᏦᎢᏍᎪ ᏅᎩ")
+      , (300, "ᏦᏍᎪᎯᏥᏆ")
+      , (301, "ᏦᎢ ᏍᎪᎯᏥᏆ ᏌᏬ")
+      , (400, "ᏅᎩᏍᎪᎯᏥᏆ")
+      , (500, "ᎯᏍᎩᏍᎪᎯᏥᏆ")
+      , (600, "ᏑᏓᎵᏍᎪᎯᏥᏆ")
+      , (700, "ᎦᎵᏆᏍᎪᎯᏥᏆ")
+      , (707, "ᎦᎵᏉᎩ ᏍᎪᎯᏥᏆ ᎦᎵᏉᎩ")
+      , (800, "ᏧᏁᎵᏍᎪᎯᏥᏆ")
+      , (900, "ᏐᏁᎵᏍᎪᎯᏥᏆ")
+      , (901, "ᏐᏁᎵ ᏍᎪᎯᏥᏆ ᏌᏬ")
+      , (999, "ᏐᏁᎵ ᏍᎪᎯᏥᏆ ᏐᏁᎳᏍᎪ ᏐᏁᎳ")
+      , (1000, "ᏐᏬ ᎢᏯᎦᏴᎵ")
+      , (1001, "ᏐᏬ ᎢᏯᎦᏴᎵ ᏌᏬ")
+      , (1100, "ᏐᏬ ᎢᏯᎦᏴᎵ ᏍᎪᎯᏥᏆ")
+      , (1101, "ᏐᏬ ᎢᏯᎦᏴᎵ ᏐᏬ ᏍᎪᎯᏥᏆ ᏌᏬ")
+      , (1111, "ᏐᏬ ᎢᏯᎦᏴᎵ ᏐᏬ ᏍᎪᎯᏥᏆ ᏌᏚ")
+      , (2000, "ᏔᎵ ᎢᏯᎦᏴᎵ")
+      , (3000, "ᏦᎢ ᎢᏯᎦᏴᎵ")
+      , (9999, "ᏐᏁᎳ ᎢᏯᎦᏴᎵ ᏐᏁᎵ ᏍᎪᎯᏥᏆ ᏐᏁᎳᏍᎪ ᏐᏁᎳ")
+      , (10000, "ᏍᎪᎯ ᎢᏯᎦᏴᎵ")
+      , (12345, "ᏔᎵᏚ ᎢᏯᎦᏴᎵ ᏦᎢ ᏍᎪᎯᏥᏆ ᏅᎩᏍᎪ ᎯᏍᎩ")
+      , (54321, "ᎯᏍᎩᏍᎪ ᏅᎩ ᎢᏯᎦᏴᎵ ᏦᎢ ᏍᎪᎯᏥᏆ ᏔᎵᏍᎪ ᏌᏬ")
+      , (99999, "ᏐᏁᎳᏍᎪ ᏐᏁᎳ ᎢᏯᎦᏴᎵ ᏐᏁᎵ ᏍᎪᎯᏥᏆ ᏐᏁᎳᏍᎪ ᏐᏁᎳ")
+      , (100000, "ᏐᏬ ᏍᎪᎯᏥᏆ ᎢᏯᎦᏴᎵ")
+      , (123456, "ᏐᏬ ᏍᎪᎯᏥᏆ ᏔᎵᏍᎪ ᏦᎢ ᎢᏯᎦᏴᎵ ᏅᎩ ᏍᎪᎯᏥᏆ ᎯᏍᎩᏍᎪ ᏑᏓᎵ")
+      , (200000, "ᏔᎵ ᏍᎪᎯᏥᏆ ᎢᏯᎦᏴᎵ")
+      , (300000, "ᏦᎢ ᏍᎪᎯᏥᏆ ᎢᏯᎦᏴᎵ")
+      , (400000, "ᏅᎩ ᏍᎪᎯᏥᏆ ᎢᏯᎦᏴᎵ")
+      , (500000, "ᎯᏍᎩ ᏍᎪᎯᏥᏆ ᎢᏯᎦᏴᎵ")
+      , (600000, "ᏑᏓᎵ ᏍᎪᎯᏥᏆ ᎢᏯᎦᏴᎵ")
+      , (654321, "ᏑᏓᎵ ᏍᎪᎯᏥᏆ ᎯᏍᎩᏍᎪ ᏅᎩ ᎢᏯᎦᏴᎵ ᏦᎢ ᏍᎪᎯᏥᏆ ᏔᎵᏍᎪ ᏌᏬ")
+      , (700000, "ᎦᎵᏉᎩ ᏍᎪᎯᏥᏆ ᎢᏯᎦᏴᎵ")
+      , (800000, "ᏧᏁᎳ ᏍᎪᎯᏥᏆ ᎢᏯᎦᏴᎵ")
+      , (900000, "ᏐᏁᎵ ᏍᎪᎯᏥᏆ ᎢᏯᎦᏴᎵ")
+      , (999999, "ᏐᏁᎵ ᏍᎪᎯᏥᏆ ᏐᏁᎳᏍᎪ ᏐᏁᎳ ᎢᏯᎦᏴᎵ ᏐᏁᎵ ᏍᎪᎯᏥᏆ ᏐᏁᎳᏍᎪ ᏐᏁᎳ")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/CLM/TestData.hs b/src-test/Text/Numeral/Language/CLM/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/CLM/TestData.hs
@@ -0,0 +1,151 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2B@]       -
+
+[@ISO639-3@]        clm
+
+[@Native name@]     nəxʷsƛ̕ay̕əmúcən
+
+[@English name@]    Klallam
+-}
+
+module Text.Numeral.Language.CLM.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "nə́c̕uʔ")
+      , (2, "čə́saʔ")
+      , (3, "ɬíxʷ")
+      , (4, "ŋús")
+      , (5, "ɬq̕áčš")
+      , (6, "t̕x̣ə́ŋ")
+      , (7, "c̕úʔkʷs")
+      , (8, "táʔcs")
+      , (9, "tə́kʷxʷ")
+      , (10, "ʔúpən")
+      , (11, "ʔúpən ʔiʔ nə́c̕uʔ")
+      , (12, "ʔúpən ʔiʔ čə́saʔ")
+      , (13, "ʔúpən ʔiʔ ɬíxʷ")
+      , (14, "ʔúpən ʔiʔ ŋús")
+      , (15, "ʔúpən ʔiʔ ɬq̕áčš")
+      , (16, "ʔúpən ʔiʔ t̕x̣ə́ŋ")
+      , (17, "ʔúpən ʔiʔ c̕úʔkʷs")
+      , (18, "ʔúpən ʔiʔ táʔcs")
+      , (19, "ʔúpən ʔiʔ tə́kʷxʷ")
+      , (20, "nəc̕xʷk̕ʷə́s")
+      , (21, "nəc̕xʷk̕ʷə́s ʔiʔ nə́c̕uʔ")
+      , (22, "nəc̕xʷk̕ʷə́s ʔiʔ čə́saʔ")
+      , (23, "nəc̕xʷk̕ʷə́s ʔiʔ ɬíxʷ")
+      , (24, "nəc̕xʷk̕ʷə́s ʔiʔ ŋús")
+      , (25, "nəc̕xʷk̕ʷə́s ʔiʔ ɬq̕áčš")
+      , (26, "nəc̕xʷk̕ʷə́s ʔiʔ t̕x̣ə́ŋ")
+      , (27, "nəc̕xʷk̕ʷə́s ʔiʔ c̕úʔkʷs")
+      , (28, "nəc̕xʷk̕ʷə́s ʔiʔ táʔcs")
+      , (29, "nəc̕xʷk̕ʷə́s ʔiʔ tə́kʷxʷ")
+      , (30, "ɬxʷɬšáʔ")
+      , (31, "ɬxʷɬšáʔ ʔiʔ nə́c̕uʔ")
+      , (32, "ɬxʷɬšáʔ ʔiʔ čə́saʔ")
+      , (33, "ɬxʷɬšáʔ ʔiʔ ɬíxʷ")
+      , (34, "ɬxʷɬšáʔ ʔiʔ ŋús")
+      , (35, "ɬxʷɬšáʔ ʔiʔ ɬq̕áčš")
+      , (36, "ɬxʷɬšáʔ ʔiʔ t̕x̣ə́ŋ")
+      , (37, "ɬxʷɬšáʔ ʔiʔ c̕úʔkʷs")
+      , (38, "ɬxʷɬšáʔ ʔiʔ táʔcs")
+      , (39, "ɬxʷɬšáʔ ʔiʔ tə́kʷxʷ")
+      , (40, "ŋəsɬšáʔ")
+      , (41, "ŋəsɬšáʔ ʔiʔ nə́c̕uʔ")
+      , (42, "ŋəsɬšáʔ ʔiʔ čə́saʔ")
+      , (43, "ŋəsɬšáʔ ʔiʔ ɬíxʷ")
+      , (44, "ŋəsɬšáʔ ʔiʔ ŋús")
+      , (45, "ŋəsɬšáʔ ʔiʔ ɬq̕áčš")
+      , (46, "ŋəsɬšáʔ ʔiʔ t̕x̣ə́ŋ")
+      , (47, "ŋəsɬšáʔ ʔiʔ c̕úʔkʷs")
+      , (48, "ŋəsɬšáʔ ʔiʔ táʔcs")
+      , (49, "ŋəsɬšáʔ ʔiʔ tə́kʷxʷ")
+      , (50, "ɬq̕čšɬšáʔ")
+      , (51, "ɬq̕čšɬšáʔ ʔiʔ nə́c̕uʔ")
+      , (52, "ɬq̕čšɬšáʔ ʔiʔ čə́saʔ")
+      , (53, "ɬq̕čšɬšáʔ ʔiʔ ɬíxʷ")
+      , (54, "ɬq̕čšɬšáʔ ʔiʔ ŋús")
+      , (55, "ɬq̕čšɬšáʔ ʔiʔ ɬq̕áčš")
+      , (56, "ɬq̕čšɬšáʔ ʔiʔ t̕x̣ə́ŋ")
+      , (57, "ɬq̕čšɬšáʔ ʔiʔ c̕úʔkʷs")
+      , (58, "ɬq̕čšɬšáʔ ʔiʔ táʔcs")
+      , (59, "ɬq̕čšɬšáʔ ʔiʔ tə́kʷxʷ")
+      , (60, "t̕x̣əŋɬšáʔ")
+      , (61, "t̕x̣əŋɬšáʔ ʔiʔ nə́c̕uʔ")
+      , (62, "t̕x̣əŋɬšáʔ ʔiʔ čə́saʔ")
+      , (63, "t̕x̣əŋɬšáʔ ʔiʔ ɬíxʷ")
+      , (64, "t̕x̣əŋɬšáʔ ʔiʔ ŋús")
+      , (65, "t̕x̣əŋɬšáʔ ʔiʔ ɬq̕áčš")
+      , (66, "t̕x̣əŋɬšáʔ ʔiʔ t̕x̣ə́ŋ")
+      , (67, "t̕x̣əŋɬšáʔ ʔiʔ c̕úʔkʷs")
+      , (68, "t̕x̣əŋɬšáʔ ʔiʔ táʔcs")
+      , (69, "t̕x̣əŋɬšáʔ ʔiʔ tə́kʷxʷ")
+      , (70, "c̕aʔkʷsɬšáʔ")
+      , (71, "c̕aʔkʷsɬšáʔ ʔiʔ nə́c̕uʔ")
+      , (72, "c̕aʔkʷsɬšáʔ ʔiʔ čə́saʔ")
+      , (73, "c̕aʔkʷsɬšáʔ ʔiʔ ɬíxʷ")
+      , (74, "c̕aʔkʷsɬšáʔ ʔiʔ ŋús")
+      , (75, "c̕aʔkʷsɬšáʔ ʔiʔ ɬq̕áčš")
+      , (76, "c̕aʔkʷsɬšáʔ ʔiʔ t̕x̣ə́ŋ")
+      , (77, "c̕aʔkʷsɬšáʔ ʔiʔ c̕úʔkʷs")
+      , (78, "c̕aʔkʷsɬšáʔ ʔiʔ táʔcs")
+      , (79, "c̕aʔkʷsɬšáʔ ʔiʔ tə́kʷxʷ")
+      , (80, "taʔcsɬšáʔ")
+      , (81, "taʔcsɬšáʔ ʔiʔ nə́c̕uʔ")
+      , (82, "taʔcsɬšáʔ ʔiʔ čə́saʔ")
+      , (83, "taʔcsɬšáʔ ʔiʔ ɬíxʷ")
+      , (84, "taʔcsɬšáʔ ʔiʔ ŋús")
+      , (85, "taʔcsɬšáʔ ʔiʔ ɬq̕áčš")
+      , (86, "taʔcsɬšáʔ ʔiʔ t̕x̣ə́ŋ")
+      , (87, "taʔcsɬšáʔ ʔiʔ c̕úʔkʷs")
+      , (88, "taʔcsɬšáʔ ʔiʔ táʔcs")
+      , (89, "taʔcsɬšáʔ ʔiʔ tə́kʷxʷ")
+      , (90, "təkʷxʷɬšáʔ")
+      , (91, "təkʷxʷɬšáʔ ʔiʔ nə́c̕uʔ")
+      , (92, "təkʷxʷɬšáʔ ʔiʔ čə́saʔ")
+      , (93, "təkʷxʷɬšáʔ ʔiʔ ɬíxʷ")
+      , (94, "təkʷxʷɬšáʔ ʔiʔ ŋús")
+      , (95, "təkʷxʷɬšáʔ ʔiʔ ɬq̕áčš")
+      , (96, "təkʷxʷɬšáʔ ʔiʔ t̕x̣ə́ŋ")
+      , (97, "təkʷxʷɬšáʔ ʔiʔ c̕úʔkʷs")
+      , (98, "təkʷxʷɬšáʔ ʔiʔ táʔcs")
+      , (99, "təkʷxʷɬšáʔ ʔiʔ tə́kʷxʷ")
+      , (100, "snáč̕əwəč")
+      , (101, "snáč̕əwəč ʔiʔ nə́c̕uʔ")
+      , (107, "snáč̕əwəč ʔiʔ c̕úʔkʷs")
+      , (123, "snáč̕əwəč ʔiʔ nəc̕xʷk̕ʷə́s ʔiʔ ɬíxʷ")
+      , (199, "snáč̕əwəč ʔiʔ təkʷxʷɬšáʔ ʔiʔ tə́kʷxʷ")
+      , (200, "čə́saʔ snáč̕əwəč")
+      , (201, "čə́saʔ snáč̕əwəč ʔiʔ nə́c̕uʔ")
+      , (207, "čə́saʔ snáč̕əwəč ʔiʔ c̕úʔkʷs")
+      , (321, "ɬíxʷ snáč̕əwəč ʔiʔ nəc̕xʷk̕ʷə́s ʔiʔ nə́c̕uʔ")
+      , (909, "tə́kʷxʷ snáč̕əwəč ʔiʔ tə́kʷxʷ")
+      , (990, "tə́kʷxʷ snáč̕əwəč ʔiʔ təkʷxʷɬšáʔ")
+      , (999, "tə́kʷxʷ snáč̕əwəč ʔiʔ təkʷxʷɬšáʔ ʔiʔ tə́kʷxʷ")
+      , (1000, "ʔúpən snáč̕əwəč")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/CO/TestData.hs b/src-test/Text/Numeral/Language/CO/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/CO/TestData.hs
@@ -0,0 +1,225 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        co
+
+[@ISO639-2@]        cos
+
+[@ISO639-3@]        cos
+
+[@Native name@]     corsu
+
+[@English name@]    Corsican
+-}
+module Text.Numeral.Language.CO.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-corsican/en/cos/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "zéru")
+      , (1, "unu")
+      , (2, "dui")
+      , (3, "trè")
+      , (4, "quattru")
+      , (5, "cinque")
+      , (6, "séi")
+      , (7, "sétte")
+      , (8, "óttu")
+      , (9, "nóve")
+      , (10, "déce")
+      , (11, "òndeci")
+      , (12, "dòdeci")
+      , (13, "trèdeci")
+      , (14, "quattòrdeci")
+      , (15, "quindeci")
+      , (16, "sèdeci")
+      , (17, "dicessétte")
+      , (18, "dicióttu")
+      , (19, "dicennóve")
+      , (20, "vinti")
+      , (21, "vintunu")
+      , (22, "vintidui")
+      , (23, "vintitrè")
+      , (24, "vintiquattru")
+      , (25, "vinticinque")
+      , (26, "vintiséi")
+      , (27, "vintisétte")
+      , (28, "vintóttu")
+      , (29, "vintinóve")
+      , (30, "trènta")
+      , (31, "trèntunu")
+      , (32, "trèntadui")
+      , (33, "trèntatrè")
+      , (34, "trèntaquattru")
+      , (35, "trèntacinque")
+      , (36, "trèntaséi")
+      , (37, "trèntasétte")
+      , (38, "trèntóttu")
+      , (39, "trèntanóve")
+      , (40, "quaranta")
+      , (41, "quarantunu")
+      , (42, "quarantadui")
+      , (43, "quarantatrè")
+      , (44, "quarantaquattru")
+      , (45, "quarantacinque")
+      , (46, "quarantaséi")
+      , (47, "quarantasétte")
+      , (48, "quarantóttu")
+      , (49, "quarantanóve")
+      , (50, "cinquanta")
+      , (51, "cinquantunu")
+      , (52, "cinquantadui")
+      , (53, "cinquantatrè")
+      , (54, "cinquantaquattru")
+      , (55, "cinquantacinque")
+      , (56, "cinquantaséi")
+      , (57, "cinquantasétte")
+      , (58, "cinquantóttu")
+      , (59, "cinquantanóve")
+      , (60, "sessanta")
+      , (61, "sessantunu")
+      , (62, "sessantadui")
+      , (63, "sessantatrè")
+      , (64, "sessantaquattru")
+      , (65, "sessantacinque")
+      , (66, "sessantaséi")
+      , (67, "sessantasétte")
+      , (68, "sessantóttu")
+      , (69, "sessantanóve")
+      , (70, "settanta")
+      , (71, "settantunu")
+      , (72, "settantadui")
+      , (73, "settantatrè")
+      , (74, "settantaquattru")
+      , (75, "settantacinque")
+      , (76, "settantaséi")
+      , (77, "settantasétte")
+      , (78, "settantóttu")
+      , (79, "settantanóve")
+      , (80, "ottanta")
+      , (81, "ottantunu")
+      , (82, "ottantadui")
+      , (83, "ottantatrè")
+      , (84, "ottantaquattru")
+      , (85, "ottantacinque")
+      , (86, "ottantaséi")
+      , (87, "ottantasétte")
+      , (88, "ottantóttu")
+      , (89, "ottantanóve")
+      , (90, "novanta")
+      , (91, "novantunu")
+      , (92, "novantadui")
+      , (93, "novantatrè")
+      , (94, "novantaquattru")
+      , (95, "novantacinque")
+      , (96, "novantaséi")
+      , (97, "novantasétte")
+      , (98, "novantóttu")
+      , (99, "novantanóve")
+      , (100, "cèntu")
+      , (101, "cèntu è unu")
+      , (102, "cèntu è dui")
+      , (103, "cèntu è trè")
+      , (104, "cèntu è quattru")
+      , (105, "cèntu è cinque")
+      , (106, "cèntu è séi")
+      , (107, "cèntu è sétte")
+      , (108, "cèntu è óttu")
+      , (109, "cèntu è nóve")
+      , (110, "cèntu è déce")
+      , (123, "cèntuvintitrè")
+      , (200, "duiecèntu")
+      , (300, "trecèntu")
+      , (321, "trecèntu vintunu")
+      , (400, "quattrucèntu")
+      , (500, "cinquecèntu")
+      , (600, "séicèntu")
+      , (700, "séttecèntu")
+      , (800, "óttucèntu")
+      , (900, "nóvecèntu")
+      , (909, "nóvecèntu è nóve")
+      , (990, "nóvecèntu novanta")
+      , (999, "nóvecèntu novantanóve")
+      , (1000, "mille")
+      , (1001, "mille è unu")
+      , (1008, "mille è óttu")
+      , (1234, "mille è duiecèntu trèntaquattru")
+      , (2000, "duiemila")
+      , (3000, "trèmila")
+      , (4000, "quattrumila")
+      , (4321, "quattrumila è trecèntu vintunu")
+      , (5000, "cinquemila")
+      , (6000, "séimila")
+      , (7000, "séttemila")
+      , (8000, "óttumila")
+      , (9000, "nóvemila")
+      , (10000, "décemila")
+      , (12345, "dòdecimila è trecèntu quarantacinque")
+      , (20000, "vintimila")
+      , (30000, "trèntamila")
+      , (40000, "quarantamila")
+      , (50000, "cinquantamila")
+      , (54321, "cinquantaquattrumila è trecèntu vintunu")
+      , (60000, "sessantamila")
+      , (70000, "settantamila")
+      , (80000, "ottantamila")
+      , (90000, "novantamila")
+      , (100000, "cèntumila")
+      , (123456, "cèntuvintitrèmila è quattrucèntu cinquantaséi")
+      , (200000, "duiecèntumila")
+      , (300000, "trecèntumila")
+      , (400000, "quattrucèntumila")
+      , (500000, "cinquecèntumila")
+      , (600000, "séicèntumila")
+      , (654321, "séicèntu cinquantaquattrumila è trecèntu vintunu")
+      , (700000, "séttecèntumila")
+      , (800000, "óttucèntumila")
+      , (900000, "nóvecèntumila")
+      , (1000000, "un miliòne")
+      , (1000001, "un miliòne è unu")
+      , (1234567, "un miliòne è duiecèntu trèntaquattrumila è cinquecèntu sessantasétte")
+      , (2000000, "dui milioni")
+      , (3000000, "trè milioni")
+      , (4000000, "quattru milioni")
+      , (5000000, "cinque milioni")
+      , (6000000, "séi milioni")
+      , (7000000, "sétte milioni")
+      , (7654321, "sétte milioni è séicèntu cinquantaquattrumila è trecèntu vintunu")
+      , (8000000, "óttu milioni")
+      , (9000000, "nóve milioni")
+      , (1000000000, "una miliarda")
+      , (1000000001, "una miliarda è unu")
+      , (2000000000, "duie miliarde")
+      , (3000000000, "trè miliarde")
+      , (4000000000, "quattru miliarde")
+      , (5000000000, "cinque miliarde")
+      , (6000000000, "séi miliarde")
+      , (7000000000, "sétte miliarde")
+      , (8000000000, "óttu miliarde")
+      , (9000000000, "nóve miliarde")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/COD/TestData.hs b/src-test/Text/Numeral/Language/COD/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/COD/TestData.hs
@@ -0,0 +1,180 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        cod
+
+[@Native name@]     Kokáma
+
+[@English name@]    Cocama
+-}
+module Text.Numeral.Language.COD.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-cocama/en/cod/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "huepe")
+      , (2, "mucuica")
+      , (3, "mutsapɨrɨca")
+      , (4, "iruaca")
+      , (5, "pichca")
+      , (6, "socta")
+      , (7, "cansi")
+      , (8, "pusa")
+      , (9, "iscun")
+      , (10, "chunga")
+      , (11, "chunga huepe")
+      , (12, "chunga mucuica")
+      , (13, "chunga mutsapɨrɨca")
+      , (14, "chunga iruaca")
+      , (15, "chunga pichca")
+      , (16, "chunga socta")
+      , (17, "chunga cansi")
+      , (18, "chunga pusa")
+      , (19, "chunga iscun")
+      , (20, "mucuica chunga")
+      , (21, "mucuica chunga huepe")
+      , (22, "mucuica chunga mucuica")
+      , (23, "mucuica chunga mutsapɨrɨca")
+      , (24, "mucuica chunga iruaca")
+      , (25, "mucuica chunga pichca")
+      , (26, "mucuica chunga socta")
+      , (27, "mucuica chunga cansi")
+      , (28, "mucuica chunga pusa")
+      , (29, "mucuica chunga iscun")
+      , (30, "mutsapɨrɨca chunga")
+      , (31, "mutsapɨrɨca chunga huepe")
+      , (32, "mutsapɨrɨca chunga mucuica")
+      , (33, "mutsapɨrɨca chunga mutsapɨrɨca")
+      , (34, "mutsapɨrɨca chunga iruaca")
+      , (35, "mutsapɨrɨca chunga pichca")
+      , (36, "mutsapɨrɨca chunga socta")
+      , (37, "mutsapɨrɨca chunga cansi")
+      , (38, "mutsapɨrɨca chunga pusa")
+      , (39, "mutsapɨrɨca chunga iscun")
+      , (40, "iruaca chunga")
+      , (41, "iruaca chunga huepe")
+      , (42, "iruaca chunga mucuica")
+      , (43, "iruaca chunga mutsapɨrɨca")
+      , (44, "iruaca chunga iruaca")
+      , (45, "iruaca chunga pichca")
+      , (46, "iruaca chunga socta")
+      , (47, "iruaca chunga cansi")
+      , (48, "iruaca chunga pusa")
+      , (49, "iruaca chunga iscun")
+      , (50, "pichca chunga")
+      , (51, "pichca chunga huepe")
+      , (52, "pichca chunga mucuica")
+      , (53, "pichca chunga mutsapɨrɨca")
+      , (54, "pichca chunga iruaca")
+      , (55, "pichca chunga pichca")
+      , (56, "pichca chunga socta")
+      , (57, "pichca chunga cansi")
+      , (58, "pichca chunga pusa")
+      , (59, "pichca chunga iscun")
+      , (60, "socta chunga")
+      , (61, "socta chunga huepe")
+      , (62, "socta chunga mucuica")
+      , (63, "socta chunga mutsapɨrɨca")
+      , (64, "socta chunga iruaca")
+      , (65, "socta chunga pichca")
+      , (66, "socta chunga socta")
+      , (67, "socta chunga cansi")
+      , (68, "socta chunga pusa")
+      , (69, "socta chunga iscun")
+      , (70, "cansi chunga")
+      , (71, "cansi chunga huepe")
+      , (72, "cansi chunga mucuica")
+      , (73, "cansi chunga mutsapɨrɨca")
+      , (74, "cansi chunga iruaca")
+      , (75, "cansi chunga pichca")
+      , (76, "cansi chunga socta")
+      , (77, "cansi chunga cansi")
+      , (78, "cansi chunga pusa")
+      , (79, "cansi chunga iscun")
+      , (80, "pusa chunga")
+      , (81, "pusa chunga huepe")
+      , (82, "pusa chunga mucuica")
+      , (83, "pusa chunga mutsapɨrɨca")
+      , (84, "pusa chunga iruaca")
+      , (85, "pusa chunga pichca")
+      , (86, "pusa chunga socta")
+      , (87, "pusa chunga cansi")
+      , (88, "pusa chunga pusa")
+      , (89, "pusa chunga iscun")
+      , (90, "iscun chunga")
+      , (91, "iscun chunga huepe")
+      , (92, "iscun chunga mucuica")
+      , (93, "iscun chunga mutsapɨrɨca")
+      , (94, "iscun chunga iruaca")
+      , (95, "iscun chunga pichca")
+      , (96, "iscun chunga socta")
+      , (97, "iscun chunga cansi")
+      , (98, "iscun chunga pusa")
+      , (99, "iscun chunga iscun")
+      , (100, "pacha")
+      , (101, "pacha huepe")
+      , (102, "pacha mucuica")
+      , (103, "pacha mutsapɨrɨca")
+      , (104, "pacha iruaca")
+      , (105, "pacha pichca")
+      , (106, "pacha socta")
+      , (107, "pacha cansi")
+      , (108, "pacha pusa")
+      , (109, "pacha iscun")
+      , (110, "pacha chunga")
+      , (123, "pacha mucuica chunga mutsapɨrɨca")
+      , (200, "mucuica pacha")
+      , (300, "mutsapɨrɨca pacha")
+      , (321, "mutsapɨrɨca pacha mucuica chunga huepe")
+      , (400, "iruaca pacha")
+      , (500, "pichca pacha")
+      , (600, "socta pacha")
+      , (700, "cansi pacha")
+      , (800, "pusa pacha")
+      , (900, "iscun pacha")
+      , (909, "iscun pacha iscun")
+      , (990, "iscun pacha iscun chunga")
+      , (999, "iscun pacha iscun chunga iscun")
+      , (1000, "huaranga")
+      , (1001, "huaranga huepe")
+      , (1008, "huaranga pusa")
+      , (1234, "huaranga mucuica pacha mutsapɨrɨca chunga iruaca")
+      , (2000, "mucuica huaranga")
+      , (3000, "mutsapɨrɨca huaranga")
+      , (4000, "iruaca huaranga")
+      , (4321, "iruaca huaranga mutsapɨrɨca pacha mucuica chunga huepe")
+      , (5000, "pichca huaranga")
+      , (6000, "socta huaranga")
+      , (7000, "cansi huaranga")
+      , (8000, "pusa huaranga")
+      , (9000, "iscun huaranga")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/COO/TestData.hs b/src-test/Text/Numeral/Language/COO/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/COO/TestData.hs
@@ -0,0 +1,144 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        coo
+
+[@Native name@]     -
+
+[@English name@]    Comox
+-}
+module Text.Numeral.Language.COO.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-comox/en/coo/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "paʔa")
+      , (2, "saʔa")
+      , (3, "čɛlas")
+      , (4, "mos")
+      , (5, "θiyɛčɩs")
+      , (6, "t̓əxəm")
+      , (7, "tᶿočɩs")
+      , (8, "taʔačɩs")
+      , (9, "tɩgiχʷ")
+      , (10, "opən")
+      , (11, "ʔopən hekʷ paʔa")
+      , (12, "ʔopən hekʷ saʔa")
+      , (13, "ʔopən hekʷ čɛlas")
+      , (14, "ʔopən hekʷ mos")
+      , (15, "ʔopən hekʷ θiyɛčɩs")
+      , (16, "ʔopən hekʷ t̓əxəm")
+      , (17, "ʔopən hekʷ tᶿočɩs")
+      , (18, "ʔopən hekʷ taʔačɩs")
+      , (19, "ʔopən hekʷ tɩgiχʷ")
+      , (20, "θamšɛ")
+      , (21, "θamšɛ heykʷ paʔa")
+      , (22, "θamšɛ heykʷ saʔa")
+      , (23, "θamšɛ heykʷ čɛlas")
+      , (24, "θamšɛ heykʷ mos")
+      , (25, "θamšɛ heykʷ θiyɛčɩs")
+      , (26, "θamšɛ heykʷ t̓əxəm")
+      , (27, "θamšɛ heykʷ tᶿočɩs")
+      , (28, "θamšɛ heykʷ taʔačɩs")
+      , (29, "θamšɛ heykʷ tɩgiχʷ")
+      , (30, "čɩnuxʷ šɛ")
+      , (31, "čɩnuxʷ šɛ heykʷ paʔa")
+      , (32, "čɩnuxʷ šɛ heykʷ saʔa")
+      , (33, "čɩnuxʷ šɛ heykʷ čɛlas")
+      , (34, "čɩnuxʷ šɛ heykʷ mos")
+      , (35, "čɩnuxʷ šɛ heykʷ θiyɛčɩs")
+      , (36, "čɩnuxʷ šɛ heykʷ t̓əxəm")
+      , (37, "čɩnuxʷ šɛ heykʷ tᶿočɩs")
+      , (38, "čɩnuxʷ šɛ heykʷ taʔačɩs")
+      , (39, "čɩnuxʷ šɛ heykʷ tɩgiχʷ")
+      , (40, "mosaɬ šɛ")
+      , (41, "mosaɬ šɛ heykʷ paʔa")
+      , (42, "mosaɬ šɛ heykʷ saʔa")
+      , (43, "mosaɬ šɛ heykʷ čɛlas")
+      , (44, "mosaɬ šɛ heykʷ mos")
+      , (45, "mosaɬ šɛ heykʷ θiyɛčɩs")
+      , (46, "mosaɬ šɛ heykʷ t̓əxəm")
+      , (47, "mosaɬ šɛ heykʷ tᶿočɩs")
+      , (48, "mosaɬ šɛ heykʷ taʔačɩs")
+      , (49, "mosaɬ šɛ heykʷ tɩgiχʷ")
+      , (50, "θiyɛčɩsaɬšɛ")
+      , (51, "θiyɛčɩsaɬšɛ heykʷ paʔa")
+      , (52, "θiyɛčɩsaɬšɛ heykʷ saʔa")
+      , (53, "θiyɛčɩsaɬšɛ heykʷ čɛlas")
+      , (54, "θiyɛčɩsaɬšɛ heykʷ mos")
+      , (55, "θiyɛčɩsaɬšɛ heykʷ θiyɛčɩs")
+      , (56, "θiyɛčɩsaɬšɛ heykʷ t̓əxəm")
+      , (57, "θiyɛčɩsaɬšɛ heykʷ tᶿočɩs")
+      , (58, "θiyɛčɩsaɬšɛ heykʷ taʔačɩs")
+      , (59, "θiyɛčɩsaɬšɛ heykʷ tɩgiχʷ")
+      , (60, "t̓əχmaɬ šɛ")
+      , (61, "t̓əχmaɬ šɛ heykʷ paʔa")
+      , (62, "t̓əχmaɬ šɛ heykʷ saʔa")
+      , (63, "t̓əχmaɬ šɛ heykʷ čɛlas")
+      , (64, "t̓əχmaɬ šɛ heykʷ mos")
+      , (65, "t̓əχmaɬ šɛ heykʷ θiyɛčɩs")
+      , (66, "t̓əχmaɬ šɛ heykʷ t̓əxəm")
+      , (67, "t̓əχmaɬ šɛ heykʷ tᶿočɩs")
+      , (68, "t̓əχmaɬ šɛ heykʷ taʔačɩs")
+      , (69, "t̓əχmaɬ šɛ heykʷ tɩgiχʷ")
+      , (70, "tᶿočɩsaɬ šɛ")
+      , (71, "tᶿočɩsaɬ šɛ heykʷ paʔa")
+      , (72, "tᶿočɩsaɬ šɛ heykʷ saʔa")
+      , (73, "tᶿočɩsaɬ šɛ heykʷ čɛlas")
+      , (74, "tᶿočɩsaɬ šɛ heykʷ mos")
+      , (75, "tᶿočɩsaɬ šɛ heykʷ θiyɛčɩs")
+      , (76, "tᶿočɩsaɬ šɛ heykʷ t̓əxəm")
+      , (77, "tᶿočɩsaɬ šɛ heykʷ tᶿočɩs")
+      , (78, "tᶿočɩsaɬ šɛ heykʷ taʔačɩs")
+      , (79, "tᶿočɩsaɬ šɛ heykʷ tɩgiχʷ")
+      , (80, "taʔačɩsaɬ šɛ")
+      , (81, "taʔačɩsaɬ šɛ heykʷ paʔa")
+      , (82, "taʔačɩsaɬ šɛ heykʷ saʔa")
+      , (83, "taʔačɩsaɬ šɛ heykʷ čɛlas")
+      , (84, "taʔačɩsaɬ šɛ heykʷ mos")
+      , (85, "taʔačɩsaɬ šɛ heykʷ θiyɛčɩs")
+      , (86, "taʔačɩsaɬ šɛ heykʷ t̓əxəm")
+      , (87, "taʔačɩsaɬ šɛ heykʷ tᶿočɩs")
+      , (88, "taʔačɩsaɬ šɛ heykʷ taʔačɩs")
+      , (89, "taʔačɩsaɬ šɛ heykʷ tɩgiχʷ")
+      , (90, "tɩgixʷaɬ šɛ")
+      , (91, "tɩgixʷaɬ šɛ heykʷ paʔa")
+      , (92, "tɩgixʷaɬ šɛ heykʷ saʔa")
+      , (93, "tɩgixʷaɬ šɛ heykʷ čɛlas")
+      , (94, "tɩgixʷaɬ šɛ heykʷ mos")
+      , (95, "tɩgixʷaɬ šɛ heykʷ θiyɛčɩs")
+      , (96, "tɩgixʷaɬ šɛ heykʷ t̓əxəm")
+      , (97, "tɩgixʷaɬ šɛ heykʷ tᶿočɩs")
+      , (98, "tɩgixʷaɬ šɛ heykʷ taʔačɩs")
+      , (99, "tɩgixʷaɬ šɛ heykʷ tɩgiχʷ")
+      , (100, "opən təsɛʔɛč")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/CS/TestData.hs b/src-test/Text/Numeral/Language/CS/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/CS/TestData.hs
@@ -0,0 +1,212 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        cs
+
+[@ISO639-2B@]       cze
+
+[@ISO639-2T@]       ces
+
+[@ISO639-3@]        ces
+
+[@Native name@]     Čeština
+
+[@English name@]    Czech
+-}
+
+module Text.Numeral.Language.CS.TestData (cardinals, ordinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "nula")
+      , (1, "jeden")
+      , (2, "dva")
+      , (3, "tři")
+      , (4, "čtyři")
+      , (5, "pět")
+      , (6, "šest")
+      , (7, "sedm")
+      , (8, "osm")
+      , (9, "devět")
+      , (10, "deset")
+      , (11, "jedenáct")
+      , (12, "dvanáct")
+      , (13, "třináct")
+      , (14, "ctrnáct")
+      , (15, "patnáct")
+      , (16, "šestnáct")
+      , (17, "sedmnáct")
+      , (18, "osmnáct")
+      , (19, "devatenáct")
+      , (20, "dvacet")
+      , (21, "dvacet jedna")
+      , (22, "dvacet dva")
+      , (23, "dvacet tři")
+      , (24, "dvacet čtyři")
+      , (25, "dvacet pět")
+      , (26, "dvacet šest")
+      , (27, "dvacet sedm")
+      , (28, "dvacet osm")
+      , (29, "dvacet devět")
+      , (30, "třicet")
+      , (31, "třicet jedna")
+      , (32, "třicet dva")
+      , (33, "třicet tři")
+      , (34, "třicet čtyři")
+      , (35, "třicet pět")
+      , (36, "třicet šest")
+      , (37, "třicet sedm")
+      , (38, "třicet osm")
+      , (39, "třicet devět")
+      , (40, "čtyřicet")
+      , (41, "čtyřicet jedna")
+      , (42, "čtyřicet dva")
+      , (43, "čtyřicet tři")
+      , (44, "čtyřicet čtyři")
+      , (45, "čtyřicet pět")
+      , (46, "čtyřicet šest")
+      , (47, "čtyřicet sedm")
+      , (48, "čtyřicet osm")
+      , (49, "čtyřicet devět")
+      , (50, "padesát")
+      , (51, "padesát jedna")
+      , (52, "padesát dva")
+      , (53, "padesát tři")
+      , (54, "padesát čtyři")
+      , (55, "padesát pět")
+      , (56, "padesát šest")
+      , (57, "padesát sedm")
+      , (58, "padesát osm")
+      , (59, "padesát devět")
+      , (60, "šedesát")
+      , (61, "šedesát jedna")
+      , (62, "šedesát dva")
+      , (63, "šedesát tři")
+      , (64, "šedesát čtyři")
+      , (65, "šedesát pět")
+      , (66, "šedesát šest")
+      , (67, "šedesát sedm")
+      , (68, "šedesát osm")
+      , (69, "šedesát devět")
+      , (70, "sedmdesát")
+      , (71, "sedmdesát jedna")
+      , (72, "sedmdesát dva")
+      , (73, "sedmdesát tři")
+      , (74, "sedmdesát čtyři")
+      , (75, "sedmdesát pět")
+      , (76, "sedmdesát šest")
+      , (77, "sedmdesát sedm")
+      , (78, "sedmdesát osm")
+      , (79, "sedmdesát devět")
+      , (80, "osmdesát")
+      , (81, "osmdesát jedna")
+      , (82, "osmdesát dva")
+      , (83, "osmdesát tři")
+      , (84, "osmdesát čtyři")
+      , (85, "osmdesát pět")
+      , (86, "osmdesát šest")
+      , (87, "osmdesát sedm")
+      , (88, "osmdesát osm")
+      , (89, "osmdesát devět")
+      , (90, "devádesát")
+      , (91, "devádesát jedna")
+      , (92, "devádesát dva")
+      , (93, "devádesát tři")
+      , (94, "devádesát čtyři")
+      , (95, "devádesát pět")
+      , (96, "devádesát šest")
+      , (97, "devádesát sedm")
+      , (98, "devádesát osm")
+      , (99, "devádesát devět")
+      , (100, "sto")
+      , (101, "sto jedna")
+      , (102, "sto dva")
+      , (110, "sto deset")
+      , (120, "sto dvacet")
+      , (200, "dvě stě")
+      , (201, "dvě stě jedna") -- or is it "dvě stě jeden"?
+      , (300, "tři sta")
+      , (400, "čtyři sta")
+      , (500, "pět set")
+      , (600, "šest set")
+      , (700, "sedm set")
+      , (800, "osm set")
+      , (900, "devět set")
+      , (1000, "tisíc")
+      , (1001, "tisíc jedna") -- or is it "tisíc jeden"?
+      , (2000, "dva tisíce")
+      , (2007, "dva tisíce sedm")
+      , (2008, "dva tisíce osm")
+      , (3000, "tři tisíce")
+      , (4000, "čtyři tisíce")
+      , (5000, "pět tisíc")
+      , (6000, "šest tisíc")
+      , (7000, "sedm tisíc")
+      , (8000, "osm tisíc")
+      , (9000, "devět tisíc")
+      , (10000, "deset tisíc")
+      , (11000, "jedenáct tisíc")
+      , (25000, "dvacet pět tisíc")
+      , (50000, "padesát tisíc")
+      , (dec 5, "sto tisíc")
+      , (138000, "sto třicet osm tisíc")
+      , (dec 6, "milión")
+      , (2 ⋅ dec 6, "dva milióny")
+      , (5 ⋅ dec 6, "pět miliónů")
+      , (6 ⋅ dec 6, "šest miliónů")
+      , (7 ⋅ dec 6, "sedm miliónů")
+      , (dec 9, "miliarda")
+      , (dec 12, "bilión")
+      ]
+    )
+  ]
+
+ordinals ∷ (Integral i) ⇒ TestData i
+ordinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "první")
+      , (2, "druhý")
+      , (3, "třetí")
+      , (4, "čtvrtý")
+      , (5, "pátý")
+      , (6, "šestý")
+      , (7, "sedmý")
+      , (8, "osmý")
+      , (9, "devátý")
+      , (10, "desátý")
+      , (11, "jedenáctý")
+      , (12, "dvanáctý")
+      , (13, "třináctý")
+      , (14, "čtrnáctý")
+      , (15, "patnáctý")
+      , (16, "šestnáctý")
+      , (17, "sedmnáctý")
+      , (18, "osmnáctý")
+      , (19, "devatenáctý")
+      , (20, "dvacátý")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/CY/TestData.hs b/src-test/Text/Numeral/Language/CY/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/CY/TestData.hs
@@ -0,0 +1,178 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        cy
+
+[@ISO639-2B@]       wel
+
+[@ISO639-2T@]       cym
+
+[@ISO639-3@]        cym
+
+[@Native name@]     Cymraeg
+
+[@English name@]    Welsh
+-}
+
+module Text.Numeral.Language.CY.TestData (cardinals, ordinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+-- Sources:
+--   http://mylanguages.org/welsh_numbers.php
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "dim")
+      , (1, "un")
+      , (2, "dau")
+      , (3, "tri")
+      , (4, "pedwar")
+      , (5, "pump")
+      , (6, "chwech")
+      , (7, "saith")
+      , (8, "wyth")
+      , (9, "naw")
+      , (10, "deg")
+      , (11, "un deg un")
+      , (12, "un deg dau")
+      , (13, "un deg tri")
+      , (14, "un deg pedwar")
+      , (15, "un deg pump")
+      , (16, "un deg chwech")
+      , (17, "un deg saith")
+      , (18, "un deg wyth")
+      , (19, "un deg naw")
+      , (20, "dau deg")
+      , (21, "dau deg un")
+      , (22, "dau deg dau")
+      , (23, "dau deg tri")
+      , (24, "dau deg pedwar")
+      , (25, "dau deg pump")
+      , (26, "dau deg chwech")
+      , (27, "dau deg saith")
+      , (28, "dau deg wyth")
+      , (29, "dau deg naw")
+      , (30, "tri deg")
+      , (31, "tri deg un")
+      , (32, "tri deg dau")
+      , (33, "tri deg tri")
+      , (34, "tri deg pedwar")
+      , (35, "tri deg pump")
+      , (36, "tri deg chwech")
+      , (37, "tri deg saith")
+      , (38, "tri deg wyth")
+      , (39, "tri deg naw")
+      , (40, "pedwar deg")
+      , (41, "pedwar deg un")
+      , (42, "pedwar deg dau")
+      , (43, "pedwar deg tri")
+      , (44, "pedwar deg pedwar")
+      , (45, "pedwar deg pump")
+      , (46, "pedwar deg chwech")
+      , (47, "pedwar deg saith")
+      , (48, "pedwar deg wyth")
+      , (49, "pedwar deg naw")
+      , (50, "pum deg")
+      , (51, "pum deg un")
+      , (52, "pum deg dau")
+      , (53, "pum deg tri")
+      , (54, "pum deg pedwar")
+      , (55, "pum deg pump")
+      , (56, "pum deg chwech")
+      , (57, "pum deg saith")
+      , (58, "pum deg wyth")
+      , (59, "pum deg naw")
+      , (60, "chwe deg")
+      , (61, "chwe deg un")
+      , (62, "chwe deg dau")
+      , (63, "chwe deg tri")
+      , (64, "chwe deg pedwar")
+      , (65, "chwe deg pump")
+      , (66, "chwe deg chwech")
+      , (67, "chwe deg saith")
+      , (68, "chwe deg wyth")
+      , (69, "chwe deg naw")
+      , (70, "saith deg")
+      , (71, "saith deg un")
+      , (72, "saith deg dau")
+      , (73, "saith deg tri")
+      , (74, "saith deg pedwar")
+      , (75, "saith deg pump")
+      , (76, "saith deg chwech")
+      , (77, "saith deg saith")
+      , (78, "saith deg wyth")
+      , (79, "saith deg naw")
+      , (80, "wyth deg")
+      , (81, "wyth deg un")
+      , (82, "wyth deg dau")
+      , (83, "wyth deg tri")
+      , (84, "wyth deg pedwar")
+      , (85, "wyth deg pump")
+      , (86, "wyth deg chwech")
+      , (87, "wyth deg saith")
+      , (88, "wyth deg wyth")
+      , (89, "wyth deg naw")
+      , (90, "naw deg")
+      , (91, "naw deg un")
+      , (92, "naw deg dau")
+      , (93, "naw deg tri")
+      , (94, "naw deg pedwar")
+      , (95, "naw deg pump")
+      , (96, "naw deg chwech")
+      , (97, "naw deg saith")
+      , (98, "naw deg wyth")
+      , (99, "naw deg naw")
+      , (100, "cant")
+      , (1000, "un thousand")
+      , (dec 6, "miliwn")
+      ]
+    )
+  ]
+
+ordinals ∷ (Integral i) ⇒ TestData i
+ordinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "gyntaf")
+      , (2, "ail")
+      , (3, "trydydd")
+      , (4, "pedwerydd")
+      , (5, "pumed")
+      , (6, "chweched")
+      , (7, "seithfed")
+      , (8, "wythfed")
+      , (9, "nawfed")
+      , (10, "degfed")
+      , (11, "unfed ar ddeg")
+      , (12, "deuddegfed")
+      , (13, "drydedd ar ddeg")
+      , (14, "ddeg")
+      , (15, "pymthegfed")
+      , (16, "ar bymtheg")
+      , (17, "ail ar bymtheg")
+      , (18, "deunawfed")
+      , (19, "bedwaredd ganrif ar bymtheg")
+      , (20, "ugeinfed")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/DE/TestData.hs b/src-test/Text/Numeral/Language/DE/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/DE/TestData.hs
@@ -0,0 +1,475 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        de
+
+[@ISO639-2B@]       ger
+
+[@ISO639-2T@]       deu
+
+[@ISO639-3@]        deu
+
+[@Native name@]     Deutsch
+
+[@English name@]    German
+-}
+
+module Text.Numeral.Language.DE.TestData (cardinals, ordinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://de.wikipedia.org/wiki/Zahlennamen
+  http://german.about.com/library/blzahlen.htm
+-}
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "null")
+      , (1, "eins")
+      , (2, "zwei")
+      , (3, "drei")
+      , (4, "vier")
+      , (5, "fünf")
+      , (6, "sechs")
+      , (7, "sieben")
+      , (8, "acht")
+      , (9, "neun")
+      , (10, "zehn")
+      , (11, "elf")
+      , (12, "zwölf")
+      , (13, "dreizehn")
+      , (14, "vierzehn")
+      , (15, "fünfzehn")
+      , (16, "sechzehn")
+      , (17, "siebzehn")
+      , (18, "achtzehn")
+      , (19, "neunzehn")
+      , (20, "zwanzig")
+      , (21, "einundzwanzig")
+      , (22, "zweiundzwanzig")
+      , (23, "dreiundzwanzig")
+      , (24, "vierundzwanzig")
+      , (25, "fünfundzwanzig")
+      , (26, "sechsundzwanzig")
+      , (27, "siebenundzwanzig")
+      , (28, "achtundzwanzig")
+      , (29, "neunundzwanzig")
+      , (30, "dreißig")
+      , (31, "einunddreißig")
+      , (32, "zweiunddreißig")
+      , (33, "dreiunddreißig")
+      , (34, "vierunddreißig")
+      , (35, "fünfunddreißig")
+      , (36, "sechsunddreißig")
+      , (37, "siebenunddreißig")
+      , (38, "achtunddreißig")
+      , (39, "neununddreißig")
+      , (40, "vierzig")
+      , (41, "einundvierzig")
+      , (42, "zweiundvierzig")
+      , (43, "dreiundvierzig")
+      , (44, "vierundvierzig")
+      , (45, "fünfundvierzig")
+      , (46, "sechsundvierzig")
+      , (47, "siebenundvierzig")
+      , (48, "achtundvierzig")
+      , (49, "neunundvierzig")
+      , (50, "fünfzig")
+      , (51, "einundfünfzig")
+      , (52, "zweiundfünfzig")
+      , (53, "dreiundfünfzig")
+      , (54, "vierundfünfzig")
+      , (55, "fünfundfünfzig")
+      , (56, "sechsundfünfzig")
+      , (57, "siebenundfünfzig")
+      , (58, "achtundfünfzig")
+      , (59, "neunundfünfzig")
+      , (60, "sechzig")
+      , (61, "einundsechzig")
+      , (62, "zweiundsechzig")
+      , (63, "dreiundsechzig")
+      , (64, "vierundsechzig")
+      , (65, "fünfundsechzig")
+      , (66, "sechsundsechzig")
+      , (67, "siebenundsechzig")
+      , (68, "achtundsechzig")
+      , (69, "neunundsechzig")
+      , (70, "siebzig")
+      , (71, "einundsiebzig")
+      , (72, "zweiundsiebzig")
+      , (73, "dreiundsiebzig")
+      , (74, "vierundsiebzig")
+      , (75, "fünfundsiebzig")
+      , (76, "sechsundsiebzig")
+      , (77, "siebenundsiebzig")
+      , (78, "achtundsiebzig")
+      , (79, "neunundsiebzig")
+      , (80, "achtzig")
+      , (81, "einundachtzig")
+      , (82, "zweiundachtzig")
+      , (83, "dreiundachtzig")
+      , (84, "vierundachtzig")
+      , (85, "fünfundachtzig")
+      , (86, "sechsundachtzig")
+      , (87, "siebenundachtzig")
+      , (88, "achtundachtzig")
+      , (89, "neunundachtzig")
+      , (90, "neunzig")
+      , (91, "einundneunzig")
+      , (92, "zweiundneunzig")
+      , (93, "dreiundneunzig")
+      , (94, "vierundneunzig")
+      , (95, "fünfundneunzig")
+      , (96, "sechsundneunzig")
+      , (97, "siebenundneunzig")
+      , (98, "achtundneunzig")
+      , (99, "neunundneunzig")
+      , (100, "hundert")
+      , (101, "hunderteins")
+      , (102, "hundertzwei")
+      , (103, "hundertdrei")
+      , (153, "hundertdreiundfünfzig")
+      , (200, "zweihundert")
+      , (201, "zweihunderteins")
+      , (202, "zweihundertzwei")
+      , (203, "zweihundertdrei")
+      , (204, "zweihundertvier")
+      , (205, "zweihundertfünf")
+      , (206, "zweihundertsechs")
+      , (207, "zweihundertsieben")
+      , (208, "zweihundertacht")
+      , (209, "zweihundertneun")
+      , (210, "zweihundertzehn")
+      , (211, "zweihundertelf")
+      , (212, "zweihundertzwölf")
+      , (213, "zweihundertdreizehn")
+      , (214, "zweihundertvierzehn")
+      , (215, "zweihundertfünfzehn")
+      , (216, "zweihundertsechzehn")
+      , (217, "zweihundertsiebzehn")
+      , (218, "zweihundertachtzehn")
+      , (219, "zweihundertneunzehn")
+      , (220, "zweihundertzwanzig")
+      , (221, "zweihunderteinundzwanzig")
+      , (222, "zweihundertzweiundzwanzig")
+      , (223, "zweihundertdreiundzwanzig")
+      , (224, "zweihundertvierundzwanzig")
+      , (225, "zweihundertfünfundzwanzig")
+      , (226, "zweihundertsechsundzwanzig")
+      , (227, "zweihundertsiebenundzwanzig")
+      , (228, "zweihundertachtundzwanzig")
+      , (229, "zweihundertneunundzwanzig")
+      , (230, "zweihundertdreißig")
+      , (300, "dreihundert")
+      , (320, "dreihundertzwanzig")
+      , (400, "vierhundert")
+      , (421, "vierhunderteinundzwanzig")
+      , (500, "fünfhundert")
+      , (522, "fünfhundertzweiundzwanzig")
+      , (600, "sechshundert")
+      , (623, "sechshundertdreiundzwanzig")
+      , (700, "siebenhundert")
+      , (724, "siebenhundertvierundzwanzig")
+      , (800, "achthundert")
+      , (825, "achthundertfünfundzwanzig")
+      , (900, "neunhundert")
+      , (901, "neunhunderteins")
+      , (926, "neunhundertsechsundzwanzig")
+      , (998, "neunhundertachtundneunzig")
+      , (999, "neunhundertneunundneunzig")
+      , (1000, "tausend")
+      , (1001, "tausendeins")
+      , (1002, "tausendzwei")
+      , (1030, "tausenddreißig")
+      , (1031, "tausendeinunddreißig")
+      , (1032, "tausendzweiunddreißig")
+      , (1033, "tausenddreiunddreißig")
+      , (1034, "tausendvierunddreißig")
+      , (1035, "tausendfünfunddreißig")
+      , (1036, "tausendsechsunddreißig")
+      , (1037, "tausendsiebenunddreißig")
+      , (1038, "tausendachtunddreißig")
+      , (1039, "tausendneununddreißig")
+      , (1040, "tausendvierzig")
+      , (1041, "tausendeinundvierzig")
+      , (1042, "tausendzweiundvierzig")
+      , (1043, "tausenddreiundvierzig")
+      , (1044, "tausendvierundvierzig")
+      , (1045, "tausendfünfundvierzig")
+      , (1046, "tausendsechsundvierzig")
+      , (1047, "tausendsiebenundvierzig")
+      , (1048, "tausendachtundvierzig")
+      , (1049, "tausendneunundvierzig")
+      , (1050, "tausendfünfzig")
+      , (1051, "tausendeinundfünfzig")
+      , (1052, "tausendzweiundfünfzig")
+      , (1053, "tausenddreiundfünfzig")
+      , (1054, "tausendvierundfünfzig")
+      , (1055, "tausendfünfundfünfzig")
+      , (1056, "tausendsechsundfünfzig")
+      , (1057, "tausendsiebenundfünfzig")
+      , (1058, "tausendachtundfünfzig")
+      , (1059, "tausendneunundfünfzig")
+      , (1060, "tausendsechzig")
+      , (1061, "tausendeinundsechzig")
+      , (1062, "tausendzweiundsechzig")
+      , (1063, "tausenddreiundsechzig")
+      , (1064, "tausendvierundsechzig")
+      , (1065, "tausendfünfundsechzig")
+      , (1066, "tausendsechsundsechzig")
+      , (1067, "tausendsiebenundsechzig")
+      , (1068, "tausendachtundsechzig")
+      , (1069, "tausendneunundsechzig")
+      , (1070, "tausendsiebzig")
+      , (1071, "tausendeinundsiebzig")
+      , (1072, "tausendzweiundsiebzig")
+      , (1073, "tausenddreiundsiebzig")
+      , (1074, "tausendvierundsiebzig")
+      , (1075, "tausendfünfundsiebzig")
+      , (1076, "tausendsechsundsiebzig")
+      , (1077, "tausendsiebenundsiebzig")
+      , (1078, "tausendachtundsiebzig")
+      , (1079, "tausendneunundsiebzig")
+      , (1080, "tausendachtzig")
+      , (1081, "tausendeinundachtzig")
+      , (1082, "tausendzweiundachtzig")
+      , (1083, "tausenddreiundachtzig")
+      , (1084, "tausendvierundachtzig")
+      , (1085, "tausendfünfundachtzig")
+      , (1086, "tausendsechsundachtzig")
+      , (1087, "tausendsiebenundachtzig")
+      , (1088, "tausendachtundachtzig")
+      , (1089, "tausendneunundachtzig")
+      , (1090, "tausendneunzig")
+      , (1091, "tausendeinundneunzig")
+      , (1092, "tausendzweiundneunzig")
+      , (1093, "tausenddreiundneunzig")
+      , (1094, "tausendvierundneunzig")
+      , (1095, "tausendfünfundneunzig")
+      , (1096, "tausendsechsundneunzig")
+      , (1097, "tausendsiebenundneunzig")
+      , (1098, "tausendachtundneunzig")
+      , (1099, "tausendneunundneunzig")
+      , (1100, "tausendhundert")
+      , (1101, "tausendhunderteins")
+      , (1102, "tausendhundertzwei")
+      , (1103, "tausendhundertdrei")
+      , (1104, "tausendhundertvier")
+      , (1105, "tausendhundertfünf")
+      , (1106, "tausendhundertsechs")
+      , (1107, "tausendhundertsieben")
+      , (1108, "tausendhundertacht")
+      , (1109, "tausendhundertneun")
+      , (1210, "tausendzweihundertzehn")
+      , (1211, "tausendzweihundertelf")
+      , (1212, "tausendzweihundertzwölf")
+      , (1213, "tausendzweihundertdreizehn")
+      , (1214, "tausendzweihundertvierzehn")
+      , (1215, "tausendzweihundertfünfzehn")
+      , (1216, "tausendzweihundertsechzehn")
+      , (1217, "tausendzweihundertsiebzehn")
+      , (1218, "tausendzweihundertachtzehn")
+      , (1219, "tausendzweihundertneunzehn")
+      , (2000, "zweitausend")
+      , (2001, "zweitausendeins")
+      , (2002, "zweitausendzwei")
+      , (2004, "zweitausendvier")
+      , (9999, "neuntausendneunhundertneunundneunzig")
+      , (10000, "zehntausend")
+      , (20000, "zwanzigtausend")
+      , (dec 5, "hunderttausend")
+      , (dec 6, "million")
+      , (2 ⋅ dec 6, "zwei millionen")
+      , (dec 9, "milliarde")
+      , (6 ⋅ dec 9, "sechs milliarden")
+      , (dec 12, "billion")
+      , (dec 15, "billiarde")
+      , (dec 18, "trillion")
+      , (dec 21, "trilliarde")
+      , (dec 24, "quadrillion")
+      , (dec 27, "quadrilliarde")
+      , (dec 30, "quintillion")
+      , (dec 33, "quintilliarde")
+      , (dec 36, "sextillion")
+      , (dec 39, "sextilliarde")
+      , (dec 42, "septillion")
+      , (dec 45, "septilliarde")
+      , (dec 48, "oktillion")
+      , (dec 51, "oktilliarde")
+      , (dec 54, "nonillion")
+      , (dec 57, "nonilliarde")
+      , (dec 60, "dezillion")
+      , (dec 63, "dezilliarde")
+      , (dec 66, "undezillion")
+      , (dec 69, "undezilliarde")
+      , (dec 72, "duodezillion")
+      , (dec 75, "duodezilliarde")
+      , (dec 78, "tredezillion")
+      , (dec 81, "tredezilliarde")
+      , (dec 84, "quattuordezillion")
+      , (dec 87, "quattuordezilliarde")
+      , (dec 90, "quindezillion")
+      , (dec 93, "quindezilliarde")
+      , (dec 180, "trigintillion")
+      , (dec 600, "zentillion")
+      , (dec 603, "zentilliarde")
+      , (dec 6000, "millinillion")
+      ]
+    )
+  ]
+
+ordinals ∷ (Integral i) ⇒ TestData i
+ordinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "nullte")
+      , (1, "erste")
+      , (2, "zweite")
+      , (3, "dritte")
+      , (4, "vierte")
+      , (5, "fünfte")
+      , (6, "sechste")
+      , (7, "siebte")
+      , (8, "achte")
+      , (9, "neunte")
+      , (10, "zehnte")
+      , (11, "elfte")
+      , (12, "zwölfte")
+      , (13, "dreizehnte")
+      , (14, "vierzehnte")
+      , (15, "fünfzehnte")
+      , (16, "sechzehnte")
+      , (17, "siebzehnte")
+      , (18, "achtzehnte")
+      , (19, "neunzehnte")
+      , (20, "zwanzigste")
+      , (21, "einundzwanzigste")
+      , (22, "zweiundzwanzigste")
+      , (23, "dreiundzwanzigste")
+      , (24, "vierundzwanzigste")
+      , (25, "fünfundzwanzigste")
+      , (26, "sechsundzwanzigste")
+      , (27, "siebenundzwanzigste")
+      , (28, "achtundzwanzigste")
+      , (29, "neunundzwanzigste")
+      , (30, "dreißigste")
+      , (31, "einunddreißigste")
+      , (32, "zweiunddreißigste")
+      , (33, "dreiunddreißigste")
+      , (34, "vierunddreißigste")
+      , (35, "fünfunddreißigste")
+      , (36, "sechsunddreißigste")
+      , (37, "siebenunddreißigste")
+      , (38, "achtunddreißigste")
+      , (39, "neununddreißigste")
+      , (40, "vierzigste")
+      , (41, "einundvierzigste")
+      , (42, "zweiundvierzigste")
+      , (43, "dreiundvierzigste")
+      , (44, "vierundvierzigste")
+      , (45, "fünfundvierzigste")
+      , (46, "sechsundvierzigste")
+      , (47, "siebenundvierzigste")
+      , (48, "achtundvierzigste")
+      , (49, "neunundvierzigste")
+      , (50, "fünfzigste")
+      , (51, "einundfünfzigste")
+      , (52, "zweiundfünfzigste")
+      , (53, "dreiundfünfzigste")
+      , (54, "vierundfünfzigste")
+      , (55, "fünfundfünfzigste")
+      , (56, "sechsundfünfzigste")
+      , (57, "siebenundfünfzigste")
+      , (58, "achtundfünfzigste")
+      , (59, "neunundfünfzigste")
+      , (60, "sechzigste")
+      , (61, "einundsechzigste")
+      , (62, "zweiundsechzigste")
+      , (63, "dreiundsechzigste")
+      , (64, "vierundsechzigste")
+      , (65, "fünfundsechzigste")
+      , (66, "sechsundsechzigste")
+      , (67, "siebenundsechzigste")
+      , (68, "achtundsechzigste")
+      , (69, "neunundsechzigste")
+      , (70, "siebzigste")
+      , (71, "einundsiebzigste")
+      , (72, "zweiundsiebzigste")
+      , (73, "dreiundsiebzigste")
+      , (74, "vierundsiebzigste")
+      , (75, "fünfundsiebzigste")
+      , (76, "sechsundsiebzigste")
+      , (77, "siebenundsiebzigste")
+      , (78, "achtundsiebzigste")
+      , (79, "neunundsiebzigste")
+      , (80, "achtzigste")
+      , (81, "einundachtzigste")
+      , (82, "zweiundachtzigste")
+      , (83, "dreiundachtzigste")
+      , (84, "vierundachtzigste")
+      , (85, "fünfundachtzigste")
+      , (86, "sechsundachtzigste")
+      , (87, "siebenundachtzigste")
+      , (88, "achtundachtzigste")
+      , (89, "neunundachtzigste")
+      , (90, "neunzigste")
+      , (91, "einundneunzigste")
+      , (92, "zweiundneunzigste")
+      , (93, "dreiundneunzigste")
+      , (94, "vierundneunzigste")
+      , (95, "fünfundneunzigste")
+      , (96, "sechsundneunzigste")
+      , (97, "siebenundneunzigste")
+      , (98, "achtundneunzigste")
+      , (99, "neunundneunzigste")
+      , (100, "hundertste")
+      , (101, "hunderterste")
+      , (102, "hundertzweite")
+      , (103, "hundertdritte")
+      , (200, "zweihundertste")
+      , (201, "zweihunderterste")
+      , (202, "zweihundertzweite")
+      , (203, "zweihundertdritte")
+      , (900, "neunhundertste")
+      , (901, "neunhunderterste")
+      , (998, "neunhundertachtundneunzigste")
+      , (999, "neunhundertneunundneunzigste")
+      , (1000, "tausendste")
+      , (1001, "tausenderste")
+      , (1002, "tausendzweite")
+      , (2000, "zweitausendste")
+      , (2001, "zweitausenderste")
+      , (2002, "zweitausendzweite")
+      , (2004, "zweitausendvierte")
+      , (10000, "zehntausendste")
+      , (20000, "zwanzigtausendste")
+      , (dec 5, "hunderttausendste")
+      , (dec 6, "millionste")
+      , (2 ⋅ dec 6, "zwei millionste")
+      , (dec 9, "milliardste")
+      , (dec 12, "billionste")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/DJK/TestData.hs b/src-test/Text/Numeral/Language/DJK/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/DJK/TestData.hs
@@ -0,0 +1,203 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        djk
+
+[@Native name@]     Aukan
+
+[@English name@]    Ndyuka
+-}
+module Text.Numeral.Language.DJK.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-aukan/en/djk/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "wan")
+      , (2, "tu")
+      , (3, "dii")
+      , (4, "fo")
+      , (5, "feifi")
+      , (6, "sigisi")
+      , (7, "seibin")
+      , (8, "aitin")
+      , (9, "neigin")
+      , (10, "tin")
+      , (11, "elufu")
+      , (12, "twalufu")
+      , (13, "tin na dii")
+      , (14, "tin na fo")
+      , (15, "tin na feifi")
+      , (16, "tin na sigisi")
+      , (17, "tin na seibin")
+      , (18, "tin na aitin")
+      , (19, "tin a neigin")
+      , (20, "twenti")
+      , (21, "twenti a wan")
+      , (22, "twenti a tu")
+      , (23, "twenti a dii")
+      , (24, "twenti a fo")
+      , (25, "twenti a feifi")
+      , (26, "twenti a sigisi")
+      , (27, "twenti a seibin")
+      , (28, "twenti a aitin")
+      , (29, "twenti a neigin")
+      , (30, "diitenti")
+      , (31, "diitenti a wan")
+      , (32, "diitenti a tu")
+      , (33, "diitenti a dii")
+      , (34, "diitenti a fo")
+      , (35, "diitenti a feifi")
+      , (36, "diitenti a sigisi")
+      , (37, "diitenti a seibin")
+      , (38, "diitenti a aitin")
+      , (39, "diitenti a neigin")
+      , (40, "fotenti")
+      , (41, "fotenti a wan")
+      , (42, "fotenti a tu")
+      , (43, "fotenti a dii")
+      , (44, "fotenti a fo")
+      , (45, "fotenti a feifi")
+      , (46, "fotenti a sigisi")
+      , (47, "fotenti a seibin")
+      , (48, "fotenti a aitin")
+      , (49, "fotenti a neigin")
+      , (50, "feifitenti")
+      , (51, "feifitenti a wan")
+      , (52, "feifitenti a tu")
+      , (53, "feifitenti a dii")
+      , (54, "feifitenti a fo")
+      , (55, "feifitenti a feifi")
+      , (56, "feifitenti a sigisi")
+      , (57, "feifitenti a seibin")
+      , (58, "feifitenti a aitin")
+      , (59, "feifitenti a neigin")
+      , (60, "sigisitenti")
+      , (61, "sigisitenti a wan")
+      , (62, "sigisitenti a tu")
+      , (63, "sigisitenti a dii")
+      , (64, "sigisitenti a fo")
+      , (65, "sigisitenti a feifi")
+      , (66, "sigisitenti a sigisi")
+      , (67, "sigisitenti a seibin")
+      , (68, "sigisitenti a aitin")
+      , (69, "sigisitenti a neigin")
+      , (70, "seibintenti")
+      , (71, "seibintenti a wan")
+      , (72, "seibintenti a tu")
+      , (73, "seibintenti a dii")
+      , (74, "seibintenti a fo")
+      , (75, "seibintenti a feifi")
+      , (76, "seibintenti a sigisi")
+      , (77, "seibintenti a seibin")
+      , (78, "seibintenti a aitin")
+      , (79, "seibintenti a neigin")
+      , (80, "aitintenti")
+      , (81, "aitintenti a wan")
+      , (82, "aitintenti a tu")
+      , (83, "aitintenti a dii")
+      , (84, "aitintenti a fo")
+      , (85, "aitintenti a feifi")
+      , (86, "aitintenti a sigisi")
+      , (87, "aitintenti a seibin")
+      , (88, "aitintenti a aitin")
+      , (89, "aitintenti a neigin")
+      , (90, "neigintenti")
+      , (91, "neigintenti a wan")
+      , (92, "neigintenti a tu")
+      , (93, "neigintenti a dii")
+      , (94, "neigintenti a fo")
+      , (95, "neigintenti a feifi")
+      , (96, "neigintenti a sigisi")
+      , (97, "neigintenti a seibin")
+      , (98, "neigintenti a aitin")
+      , (99, "neigintenti a neigin")
+      , (100, "wan ondoo")
+      , (101, "wan ondoo anga wan")
+      , (102, "wan ondoo anga tu")
+      , (103, "wan ondoo anga dii")
+      , (104, "wan ondoo anga fo")
+      , (105, "wan ondoo anga feifi")
+      , (106, "wan ondoo anga sigisi")
+      , (107, "wan ondoo anga seibin")
+      , (108, "wan ondoo anga aitin")
+      , (109, "wan ondoo anga neigin")
+      , (110, "wan ondoo anga tin")
+      , (123, "wan ondoo anga twenti a dii")
+      , (200, "tu ondoo")
+      , (300, "dii ondoo")
+      , (321, "dii ondoo anga twenti a wan")
+      , (400, "fo ondoo")
+      , (500, "feifi ondoo")
+      , (600, "sigisi ondoo")
+      , (700, "seibin ondoo")
+      , (800, "aitin ondoo")
+      , (900, "neigin ondoo")
+      , (909, "neigin ondoo anga neigin")
+      , (990, "neigin ondoo anga neigintenti")
+      , (999, "neigin ondoo anga neigintenti a neigin")
+      , (1000, "wan dunsu")
+      , (1001, "wan dunsu wan")
+      , (1008, "wan dunsu aitin")
+      , (1234, "wan dunsu tu ondoo anga anga diitenti a fo")
+      , (2000, "tu dunsu")
+      , (3000, "dii dunsu")
+      , (4000, "fo dunsu")
+      , (4321, "fo dunsu dii ondoo anga anga twenti a wan")
+      , (5000, "feifi dunsu")
+      , (6000, "sigisi dunsu")
+      , (7000, "seibin dunsu")
+      , (8000, "aitin dunsu")
+      , (9000, "neigin dunsu")
+      , (10000, "tin dunsu")
+      , (12345, "twalufu dunsu dii ondoo anga anga fotenti a feifi")
+      , (20000, "twenti dunsu")
+      , (30000, "diitenti dunsu")
+      , (40000, "fotenti dunsu")
+      , (50000, "feifitenti dunsu")
+      , (54321, "feifitenti a fo dunsu dii ondoo anga anga twenti a wan")
+      , (60000, "sigisitenti dunsu")
+      , (70000, "seibintenti dunsu")
+      , (80000, "aitintenti dunsu")
+      , (90000, "neigintenti dunsu")
+      , (100000, "wan ondoo anga dunsu")
+      , (123456, "wan ondoo anga twenti a dii dunsu fo ondoo anga anga feifitenti a sigisi")
+      , (200000, "tu ondoo anga dunsu")
+      , (300000, "dii ondoo anga dunsu")
+      , (400000, "fo ondoo anga dunsu")
+      , (500000, "feifi ondoo anga dunsu")
+      , (600000, "sigisi ondoo anga dunsu")
+      , (654321, "sigisi ondoo anga feifitenti a fo dunsu dii ondoo anga anga twenti a wan")
+      , (700000, "seibin ondoo anga dunsu")
+      , (800000, "aitin ondoo anga dunsu")
+      , (900000, "neigin ondoo anga dunsu")
+      , (1000000, "wan miliyun")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/EN/TestData.hs b/src-test/Text/Numeral/Language/EN/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/EN/TestData.hs
@@ -0,0 +1,380 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        en
+
+[@ISO639-2B@]       eng
+
+[@ISO639-3@]        eng
+
+[@Native name@]     English
+
+[@English name@]    English
+-}
+
+module Text.Numeral.Language.EN.TestData
+    ( gb_cardinals, gb_ordinals
+    , us_cardinals, us_ordinals
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "base-unicode-symbols" Data.Monoid.Unicode ( (⊕) )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+-- Sources: http://en.wikipedia.org/wiki/List_of_numbers
+
+en_cardinals ∷ (Num i) ⇒ [(i, Text)]
+en_cardinals =
+  [ (0, "zero")
+  , (1, "one")
+  , (2, "two")
+  , (3, "three")
+  , (4, "four")
+  , (5, "five")
+  , (6, "six")
+  , (7, "seven")
+  , (8, "eight")
+  , (9, "nine")
+  , (10, "ten")
+  , (11, "eleven")
+  , (12, "twelve")
+  , (13, "thirteen")
+  , (14, "fourteen")
+  , (15, "fifteen")
+  , (16, "sixteen")
+  , (17, "seventeen")
+  , (18, "eighteen")
+  , (19, "nineteen")
+  , (20, "twenty")
+  , (21, "twenty-one")
+  , (22, "twenty-two")
+  , (23, "twenty-three")
+  , (24, "twenty-four")
+  , (25, "twenty-five")
+  , (26, "twenty-six")
+  , (27, "twenty-seven")
+  , (28, "twenty-eight")
+  , (29, "twenty-nine")
+  , (30, "thirty")
+  , (31, "thirty-one")
+  , (32, "thirty-two")
+  , (33, "thirty-three")
+  , (34, "thirty-four")
+  , (35, "thirty-five")
+  , (36, "thirty-six")
+  , (37, "thirty-seven")
+  , (38, "thirty-eight")
+  , (39, "thirty-nine")
+  , (40, "forty")
+  , (41, "forty-one")
+  , (42, "forty-two")
+  , (43, "forty-three")
+  , (44, "forty-four")
+  , (45, "forty-five")
+  , (46, "forty-six")
+  , (47, "forty-seven")
+  , (48, "forty-eight")
+  , (49, "forty-nine")
+  , (50, "fifty")
+  , (51, "fifty-one")
+  , (52, "fifty-two")
+  , (53, "fifty-three")
+  , (54, "fifty-four")
+  , (55, "fifty-five")
+  , (56, "fifty-six")
+  , (57, "fifty-seven")
+  , (58, "fifty-eight")
+  , (59, "fifty-nine")
+  , (60, "sixty")
+  , (61, "sixty-one")
+  , (62, "sixty-two")
+  , (63, "sixty-three")
+  , (64, "sixty-four")
+  , (65, "sixty-five")
+  , (66, "sixty-six")
+  , (67, "sixty-seven")
+  , (68, "sixty-eight")
+  , (69, "sixty-nine")
+  , (70, "seventy")
+  , (71, "seventy-one")
+  , (72, "seventy-two")
+  , (73, "seventy-three")
+  , (74, "seventy-four")
+  , (75, "seventy-five")
+  , (76, "seventy-six")
+  , (77, "seventy-seven")
+  , (78, "seventy-eight")
+  , (79, "seventy-nine")
+  , (80, "eighty")
+  , (81, "eighty-one")
+  , (82, "eighty-two")
+  , (83, "eighty-three")
+  , (84, "eighty-four")
+  , (85, "eighty-five")
+  , (86, "eighty-six")
+  , (87, "eighty-seven")
+  , (88, "eighty-eight")
+  , (89, "eighty-nine")
+  , (90, "ninety")
+  , (91, "ninety-one")
+  , (92, "ninety-two")
+  , (93, "ninety-three")
+  , (94, "ninety-four")
+  , (95, "ninety-five")
+  , (96, "ninety-six")
+  , (97, "ninety-seven")
+  , (98, "ninety-eight")
+  , (99, "ninety-nine")
+  , (100, "one hundred")
+  ]
+
+en_ordinals ∷ (Num i) ⇒ [(i, Text)]
+en_ordinals =
+  [ (0, "zeroth")
+  , (1, "first")
+  , (2, "second")
+  , (3, "third")
+  , (4, "fourth")
+  , (5, "fifth")
+  , (6, "sixth")
+  , (7, "seventh")
+  , (8, "eighth")
+  , (9, "ninth")
+  , (10, "tenth")
+  , (11, "eleventh")
+  , (12, "twelfth")
+  , (13, "thirteenth")
+  , (14, "fourteenth")
+  , (15, "fifteenth")
+  , (16, "sixteenth")
+  , (17, "seventeenth")
+  , (18, "eighteenth")
+  , (19, "nineteenth")
+  , (20, "twentieth")
+  , (21, "twenty-first")
+  , (22, "twenty-second")
+  , (23, "twenty-third")
+  , (24, "twenty-fourth")
+  , (25, "twenty-fifth")
+  , (26, "twenty-sixth")
+  , (27, "twenty-seventh")
+  , (28, "twenty-eighth")
+  , (29, "twenty-ninth")
+  , (30, "thirtieth")
+  , (31, "thirty-first")
+  , (32, "thirty-second")
+  , (33, "thirty-third")
+  , (34, "thirty-fourth")
+  , (35, "thirty-fifth")
+  , (36, "thirty-sixth")
+  , (37, "thirty-seventh")
+  , (38, "thirty-eighth")
+  , (39, "thirty-ninth")
+  , (40, "fortieth")
+  , (41, "forty-first")
+  , (42, "forty-second")
+  , (43, "forty-third")
+  , (44, "forty-fourth")
+  , (45, "forty-fifth")
+  , (46, "forty-sixth")
+  , (47, "forty-seventh")
+  , (48, "forty-eighth")
+  , (49, "forty-ninth")
+  , (50, "fiftieth")
+  , (51, "fifty-first")
+  , (52, "fifty-second")
+  , (53, "fifty-third")
+  , (54, "fifty-fourth")
+  , (55, "fifty-fifth")
+  , (56, "fifty-sixth")
+  , (57, "fifty-seventh")
+  , (58, "fifty-eighth")
+  , (59, "fifty-ninth")
+  , (60, "sixtieth")
+  , (61, "sixty-first")
+  , (62, "sixty-second")
+  , (63, "sixty-third")
+  , (64, "sixty-fourth")
+  , (65, "sixty-fifth")
+  , (66, "sixty-sixth")
+  , (67, "sixty-seventh")
+  , (68, "sixty-eighth")
+  , (69, "sixty-ninth")
+  , (70, "seventieth")
+  , (71, "seventy-first")
+  , (72, "seventy-second")
+  , (73, "seventy-third")
+  , (74, "seventy-fourth")
+  , (75, "seventy-fifth")
+  , (76, "seventy-sixth")
+  , (77, "seventy-seventh")
+  , (78, "seventy-eighth")
+  , (79, "seventy-ninth")
+  , (80, "eightieth")
+  , (81, "eighty-first")
+  , (82, "eighty-second")
+  , (83, "eighty-third")
+  , (84, "eighty-fourth")
+  , (85, "eighty-fifth")
+  , (86, "eighty-sixth")
+  , (87, "eighty-seventh")
+  , (88, "eighty-eighth")
+  , (89, "eighty-ninth")
+  , (90, "ninetieth")
+  , (91, "ninety-first")
+  , (92, "ninety-second")
+  , (93, "ninety-third")
+  , (94, "ninety-fourth")
+  , (95, "ninety-fifth")
+  , (96, "ninety-sixth")
+  , (97, "ninety-seventh")
+  , (98, "ninety-eighth")
+  , (99, "ninety-ninth")
+  , (100, "one hundreth")
+  ]
+
+gb_cardinals ∷ (Num i) ⇒ TestData i
+gb_cardinals =
+  [ ( "default"
+    , defaultInflection
+    , en_cardinals
+      ⊕ [ (-1, "minus one")
+        , (101, "one hundred and one")
+        , (110, "one hundred and ten")
+        , (111, "one hundred and eleven")
+        , (120, "one hundred and twenty")
+        , (121, "one hundred and twenty-one")
+        , (144, "one hundred and forty-four")
+        , (200, "two hundred")
+        , (300, "three hundred")
+        , (666, "six hundred and sixty-six")
+        , (1000, "one thousand")
+        , (1001, "one thousand and one")
+        , (1010, "one thousand and ten")
+        , (1011, "one thousand and eleven")
+        , (1024, "one thousand and twenty-four")
+        , (1100, "one thousand one hundred")
+        , (1728, "one thousand seven hundred and twenty-eight")
+        , (2000, "two thousand")
+        , (10000, "ten thousand")
+        , (100000, "one hundred thousand")
+        , (500000, "five hundred thousand")
+        , (1000000, "one million")
+        , (1048576, "one million forty-eight thousand five hundred and seventy-six")
+        , (10000000, "ten million")
+        ]
+    )
+  ]
+
+gb_ordinals ∷ (Num i) ⇒ TestData i
+gb_ordinals =
+  [ ( "default"
+    , defaultInflection
+    , en_ordinals
+      ⊕ [ (101, "one hundred and first")
+        , (110, "one hundred and tenth")
+        , (111, "one hundred and eleventh")
+        , (120, "one hundred and twentieth")
+        , (121, "one hundred and twenty-first")
+        , (144, "one hundred and forty-fourth")
+        , (200, "two hundreth")
+        , (300, "three hundreth")
+        , (666, "six hundred and sixty-sixth")
+        , (1000, "one thousandth")
+        , (1001, "one thousand and first")
+        , (1010, "one thousand and tenth")
+        , (1011, "one thousand and eleventh")
+        , (1024, "one thousand and twenty-fourth")
+        , (1100, "one thousand one hundreth")
+        , (1728, "one thousand seven hundred and twenty-eighth")
+        , (2000, "two thousandth")
+        , (10000, "ten thousandth")
+        , (100000, "one hundred thousandth")
+        , (500000, "five hundred thousandth")
+        , (1000000, "one millionth")
+        , (1048576, "one million forty-eight thousand five hundred and seventy-sixth")
+        , (10000000, "ten millionth")
+        ]
+    )
+  ]
+
+us_cardinals ∷ (Num i) ⇒ TestData i
+us_cardinals =
+  [ ( "default"
+    , defaultInflection
+    , en_cardinals
+      ⊕ [ (-1, "negative one")
+        , (101, "one hundred one")
+        , (110, "one hundred ten")
+        , (111, "one hundred eleven")
+        , (120, "one hundred twenty")
+        , (121, "one hundred twenty-one")
+        , (144, "one hundred forty-four")
+        , (200, "two hundred")
+        , (300, "three hundred")
+        , (666, "six hundred sixty-six")
+        , (1000, "one thousand")
+        , (1001, "one thousand one")
+        , (1010, "one thousand ten")
+        , (1011, "one thousand eleven")
+        , (1024, "one thousand twenty-four")
+        , (1100, "one thousand one hundred")
+        , (1728, "one thousand seven hundred twenty-eight")
+        , (2000, "two thousand")
+        , (10000, "ten thousand")
+        , (100000, "one hundred thousand")
+        , (500000, "five hundred thousand")
+        , (1000000, "one million")
+        , (1048576, "one million forty-eight thousand five hundred seventy-six")
+        , (10000000, "ten million")
+        ]
+    )
+  ]
+
+us_ordinals ∷ (Num i) ⇒ TestData i
+us_ordinals =
+  [ ( "default"
+    , defaultInflection
+    , en_ordinals
+      ⊕ [ (101, "one hundred first")
+        , (110, "one hundred tenth")
+        , (111, "one hundred eleventh")
+        , (120, "one hundred twentieth")
+        , (121, "one hundred twenty-first")
+        , (144, "one hundred forty-fourth")
+        , (200, "two hundreth")
+        , (300, "three hundreth")
+        , (666, "six hundred sixty-sixth")
+        , (1000, "one thousandth")
+        , (1001, "one thousand first")
+        , (1010, "one thousand tenth")
+        , (1011, "one thousand eleventh")
+        , (1024, "one thousand twenty-fourth")
+        , (1100, "one thousand one hundreth")
+        , (1728, "one thousand seven hundred twenty-eighth")
+        , (2000, "two thousandth")
+        , (10000, "ten thousandth")
+        , (100000, "one hundred thousandth")
+        , (500000, "five hundred thousandth")
+        , (1000000, "one millionth")
+        , (1048576, "one million forty-eight thousand five hundred seventy-sixth")
+        , (10000000, "ten millionth")
+        ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/EO/TestData.hs b/src-test/Text/Numeral/Language/EO/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/EO/TestData.hs
@@ -0,0 +1,142 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        eo
+
+[@ISO639-2B@]       epo
+
+[@ISO639-3@]        epo
+
+[@Native name@]     Esperanto
+
+[@English name@]    Esperanto
+-}
+
+module Text.Numeral.Language.EO.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "nul")
+      , (1, "unu")
+      , (2, "du")
+      , (3, "tri")
+      , (4, "kvar")
+      , (5, "kvin")
+      , (6, "ses")
+      , (7, "sep")
+      , (8, "ok")
+      , (9, "naŭ")
+      , (10, "dek")
+      , (11, "dek unu")
+      , (12, "dek du")
+      , (13, "dek tri")
+      , (14, "dek kvar")
+      , (15, "dek kvin")
+      , (16, "dek ses")
+      , (17, "dek sep")
+      , (18, "dek ok")
+      , (19, "dek naŭ")
+      , (20, "dudek")
+      , (21, "dudek unu")
+      , (22, "dudek du")
+      , (23, "dudek tri")
+      , (24, "dudek kvar")
+      , (25, "dudek kvin")
+      , (26, "dudek ses")
+      , (27, "dudek sep")
+      , (28, "dudek ok")
+      , (29, "dudek naŭ")
+      , (30, "tridek")
+      , (31, "tridek unu")
+      , (32, "tridek du")
+      , (33, "tridek tri")
+      , (34, "tridek kvar")
+      , (35, "tridek kvin")
+      , (36, "tridek ses")
+      , (37, "tridek sep")
+      , (38, "tridek ok")
+      , (39, "tridek naŭ")
+      , (40, "kvardek")
+      , (41, "kvardek unu")
+      , (42, "kvardek du")
+      , (43, "kvardek tri")
+      , (44, "kvardek kvar")
+      , (45, "kvardek kvin")
+      , (46, "kvardek ses")
+      , (47, "kvardek sep")
+      , (48, "kvardek ok")
+      , (49, "kvardek naŭ")
+      , (50, "kvindek")
+      , (51, "kvindek unu")
+      , (52, "kvindek du")
+      , (53, "kvindek tri")
+      , (54, "kvindek kvar")
+      , (55, "kvindek kvin")
+      , (56, "kvindek ses")
+      , (57, "kvindek sep")
+      , (58, "kvindek ok")
+      , (59, "kvindek naŭ")
+      , (60, "sesdek")
+      , (61, "sesdek unu")
+      , (62, "sesdek du")
+      , (63, "sesdek tri")
+      , (64, "sesdek kvar")
+      , (65, "sesdek kvin")
+      , (66, "sesdek ses")
+      , (67, "sesdek sep")
+      , (68, "sesdek ok")
+      , (69, "sesdek naŭ")
+      , (70, "sepdek")
+      , (71, "sepdek unu")
+      , (72, "sepdek du")
+      , (73, "sepdek tri")
+      , (74, "sepdek kvar")
+      , (75, "sepdek kvin")
+      , (76, "sepdek ses")
+      , (77, "sepdek sep")
+      , (78, "sepdek ok")
+      , (79, "sepdek naŭ")
+      , (80, "okdek")
+      , (81, "okdek unu")
+      , (82, "okdek du")
+      , (83, "okdek tri")
+      , (84, "okdek kvar")
+      , (85, "okdek kvin")
+      , (86, "okdek ses")
+      , (87, "okdek sep")
+      , (88, "okdek ok")
+      , (89, "okdek naŭ")
+      , (90, "naŭdek")
+      , (91, "naŭdek unu")
+      , (92, "naŭdek du")
+      , (93, "naŭdek tri")
+      , (94, "naŭdek kvar")
+      , (95, "naŭdek kvin")
+      , (96, "naŭdek ses")
+      , (97, "naŭdek sep")
+      , (98, "naŭdek ok")
+      , (99, "naŭdek naŭ")
+      , (100, "cent")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/ES/TestData.hs b/src-test/Text/Numeral/Language/ES/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/ES/TestData.hs
@@ -0,0 +1,280 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        es
+
+[@ISO639-2B@]       spa
+
+[@ISO639-3@]        spa
+
+[@Native name@]     Español
+
+[@English name@]    Spanish
+-}
+
+module Text.Numeral.Language.ES.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num, (+), Integral )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Misc ( dec )
+import "numerals" Text.Numeral.Grammar
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+-- Sources:
+--   http://www.sf.airnet.ne.jp/~ts/language/number/spanish.html
+--   http://spanish.about.com/cs/forbeginners/a/cardinalnum_beg.htm
+--   http://www.learn-spanish-help.com/count-in-spanish.html
+--   http://www.donquijote.org/spanishlanguage/numbers/numbers1.asp
+--   http://en.wiktionary.org/wiki/Appendix:Spanish_numerals
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "neuter"
+    , neuter defaultInflection
+    , [ (-3, "menos tres")
+      , (-2, "menos dos")
+      , (-1, "menos uno")
+      , (0, "cero")
+      , (1, "uno")
+      , (2, "dos")
+      , (3, "tres")
+      , (4, "cuatro")
+      , (5, "cinco")
+      , (6, "seis")
+      , (7, "siete")
+      , (8, "ocho")
+      , (9, "nueve")
+      , (10, "diez")
+      , (11, "once")
+      , (12, "doce")
+      , (13, "trece")
+      , (14, "catorce")
+      , (15, "quince")
+      , (16, "dieciséis")
+      , (17, "diecisiete")
+      , (18, "dieciocho")
+      , (19, "diecinueve")
+      , (20, "veinte")
+      , (21, "veintiuno")
+      , (22, "veintidós")
+      , (23, "veintitrés")
+      , (24, "veinticuatro")
+      , (25, "veinticinco")
+      , (26, "veintiséis")
+      , (27, "veintisiete")
+      , (28, "veintiocho")
+      , (29, "veintinueve")
+      , (30, "treinta")
+      , (31, "treinta y uno")
+      , (32, "treinta y dos")
+      , (33, "treinta y tres")
+      , (34, "treinta y cuatro")
+      , (35, "treinta y cinco")
+      , (36, "treinta y seis")
+      , (37, "treinta y siete")
+      , (38, "treinta y ocho")
+      , (39, "treinta y nueve")
+      , (40, "cuarenta")
+      , (41, "cuarenta y uno")
+      , (42, "cuarenta y dos")
+      , (43, "cuarenta y tres")
+      , (44, "cuarenta y cuatro")
+      , (45, "cuarenta y cinco")
+      , (46, "cuarenta y seis")
+      , (47, "cuarenta y siete")
+      , (48, "cuarenta y ocho")
+      , (49, "cuarenta y nueve")
+      , (50, "cincuenta")
+      , (51, "cincuenta y uno")
+      , (52, "cincuenta y dos")
+      , (53, "cincuenta y tres")
+      , (54, "cincuenta y cuatro")
+      , (55, "cincuenta y cinco")
+      , (56, "cincuenta y seis")
+      , (57, "cincuenta y siete")
+      , (58, "cincuenta y ocho")
+      , (59, "cincuenta y nueve")
+      , (60, "sesenta")
+      , (61, "sesenta y uno")
+      , (62, "sesenta y dos")
+      , (63, "sesenta y tres")
+      , (64, "sesenta y cuatro")
+      , (65, "sesenta y cinco")
+      , (66, "sesenta y seis")
+      , (67, "sesenta y siete")
+      , (68, "sesenta y ocho")
+      , (69, "sesenta y nueve")
+      , (70, "setenta")
+      , (71, "setenta y uno")
+      , (72, "setenta y dos")
+      , (73, "setenta y tres")
+      , (74, "setenta y cuatro")
+      , (75, "setenta y cinco")
+      , (76, "setenta y seis")
+      , (77, "setenta y siete")
+      , (78, "setenta y ocho")
+      , (79, "setenta y nueve")
+      , (80, "ochenta")
+      , (81, "ochenta y uno")
+      , (82, "ochenta y dos")
+      , (83, "ochenta y tres")
+      , (84, "ochenta y cuatro")
+      , (85, "ochenta y cinco")
+      , (86, "ochenta y seis")
+      , (87, "ochenta y siete")
+      , (88, "ochenta y ocho")
+      , (89, "ochenta y nueve")
+      , (90, "noventa")
+      , (91, "noventa y uno")
+      , (92, "noventa y dos")
+      , (93, "noventa y tres")
+      , (94, "noventa y cuatro")
+      , (95, "noventa y cinco")
+      , (96, "noventa y seis")
+      , (97, "noventa y siete")
+      , (98, "noventa y ocho")
+      , (99, "noventa y nueve")
+      , (100, "cien")
+      , (101, "ciento uno")
+      , (103, "ciento tres")
+      , (114, "ciento catorce")
+      , (127, "ciento veintisiete")
+      , (165, "ciento sesenta y cinco")
+      , (198, "ciento noventa y ocho")
+      , (199, "ciento noventa y nueve")
+      , (200, "doscientos")
+      , (221, "doscientos veintiuno")
+      , (256, "doscientos cincuenta y seis")
+      , (300, "trescientos")
+      , (400, "cuatrocientos")
+      , (496, "cuatrocientos noventa y seis")
+      , (500, "quinientos")
+      , (512, "quinientos doce")
+      , (600, "seiscientos")
+      , (666, "seiscientos sesenta y seis")
+      , (700, "setecientos")
+      , (800, "ochocientos")
+      , (900, "novecientos")
+      , (1000, "mil")
+      , (1002, "mil dos")
+      , (1024, "mil veinticuatro")
+      , (1729, "mil setecientos veintinueve")
+      , (2000, "dos mil")
+      , (2800, "dos mil ochocientos")
+      , (3000, "tres mil")
+      , (4000, "cuatro mil")
+      , (5000, "cinco mil")
+      , (6000, "seis mil")
+      , (7000, "siete mil")
+      , (8000, "ocho mil")
+      , (9000, "nueve mil")
+      , (dec 4, "diez mil")
+      , (15000, "quince mil")
+      , (18000, "dieciocho mil")
+      , (22000, "veintidós mil")
+      , (28000, "veintiocho mil")
+      , (37000, "treinta y siete mil")
+      , (85000, "ochenta y cinco mil")
+      , (dec 5, "cien mil")
+      , (108000, "ciento ocho mil")
+      , (160000, "ciento sesenta mil")
+      , (585000, "quinientos ochenta y cinco mil")
+      , (999000, "novecientos noventa y nueve mil")
+      , (dec 6, "un millón")
+      , (dec 6 + 1, "un millón uno")
+      , (21 ⋅ dec 6 + 21, "veintiún millones veintiuno")
+      , (500 ⋅ dec 6, "quinientos millones")
+      , (521 ⋅ dec 6 + 1, "quinientos veintiún millones uno")
+      , (dec 7, "diez millones")
+      , (dec 8, "cien millones")
+      , (dec 9, "mil millones")
+      , (dec 10, "diez mil millones")
+      , (dec 11, "cien mil millones")
+      , (dec 12, "un billón")
+      , (dec 18, "un trillón")
+      , (dec 24, "un cuatrillón")
+      , (15936535897932384626433832795, "quince mil novecientos treinta y seis cuatrillones quinientos treinta y cinco mil ochocientos noventa y siete trillones novecientos treinta y dos mil trescientos ochenta y cuatro billones seiscientos veintiséis mil cuatrocientos treinta y tres millones ochocientos treinta y dos mil setecientos noventa y cinco")
+      , (dec 30, "un quintillón")
+      , (31415926535897932384626433832795, "treinta y un quintillones cuatrocientos quince mil novecientos veintiséis cuatrillones quinientos treinta y cinco mil ochocientos noventa y siete trillones novecientos treinta y dos mil trescientos ochenta y cuatro billones seiscientos veintiséis mil cuatrocientos treinta y tres millones ochocientos treinta y dos mil setecientos noventa y cinco")
+      , (dec 36, "un sextillón")
+      , (dec 42, "un septillón")
+      , (dec 48, "un octillón")
+      , (dec 54, "un nonillón")
+      , (dec 60, "un decillón")
+      , (dec 66, "un undecillón")
+      , (dec 72, "un duodecillón")
+      , (dec 78, "un tredecillón")
+      , (dec 84, "un cuatordecillón")
+      , (dec 90, "un quindecillón")
+      , (dec 96, "un sexdecillón")
+      , (dec 102, "un septendecillón")
+      , (dec 108, "un octodecillón")
+      , (dec 114, "un novendecillón")
+      , (dec 120, "un vigintillón")
+      ]
+    )
+  , ( "feminine"
+    , feminine defaultInflection
+    , [ (1, "una")
+      , (11, "once")
+      , (21, "veintiuna")
+      , (31, "treinta y una")
+      , (41, "cuarenta y una")
+      , (51, "cincuenta y una")
+      , (61, "sesenta y una")
+      , (71, "setenta y una")
+      , (81, "ochenta y una")
+      , (91, "noventa y una")
+      , (100, "cien")
+      , (101, "ciento una")
+      , (200, "doscientas")
+      , (221, "doscientas veintiuna")
+      , (300, "trescientas")
+      , (400, "cuatrocientas")
+      , (500, "quinientas")
+      , (600, "seiscientas")
+      , (700, "setecientas")
+      , (800, "ochocientas")
+      , (900, "novecientas")
+      , (dec 6, "un millón")
+      , (dec 6 + 1, "un millón una")
+      , (21 ⋅ dec 6 + 21, "veintiún millones veintiuna")
+      ]
+    )
+  , ( "masculine"
+    , masculine defaultInflection
+    , [ (1, "un")
+      , (11, "once")
+      , (21, "veintiún")
+      , (31, "treinta y un")
+      , (41, "cuarenta y un")
+      , (51, "cincuenta y un")
+      , (61, "sesenta y un")
+      , (71, "setenta y un")
+      , (81, "ochenta y un")
+      , (91, "noventa y un")
+      , (100, "cien")
+      , (101, "ciento un")
+      , (200, "doscientos")
+      , (221, "doscientos veintiún")
+      , (dec 6, "un millón")
+      , (dec 6 + 1, "un millón un")
+      , (21 ⋅ dec 6 + 21, "veintiún millones veintiún")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/ET/TestData.hs b/src-test/Text/Numeral/Language/ET/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/ET/TestData.hs
@@ -0,0 +1,220 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        et
+
+[@ISO639-2@]        est
+
+[@ISO639-3@]        est
+
+[@Native name@]     eesti keel
+
+[@English name@]    Estonian
+-}
+
+module Text.Numeral.Language.ET.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Integral )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "null")
+      , (1, "üks")
+      , (2, "kaks")
+      , (3, "kolm")
+      , (4, "neli")
+      , (5, "viis")
+      , (6, "kuus")
+      , (7, "seitse")
+      , (8, "kaheksa")
+      , (9, "üheksa")
+      , (10, "kümme")
+      , (11, "üksteist")
+      , (12, "kaksteist")
+      , (13, "kolmteist")
+      , (14, "neliteist")
+      , (15, "viisteist")
+      , (16, "kuusteist")
+      , (17, "seitseteist")
+      , (18, "kaheksateist")
+      , (19, "üheksateist")
+      , (20, "kakskümmend")
+      , (21, "kakskümmend üks")
+      , (22, "kakskümmend kaks")
+      , (23, "kakskümmend kolm")
+      , (24, "kakskümmend neli")
+      , (25, "kakskümmend viis")
+      , (26, "kakskümmend kuus")
+      , (27, "kakskümmend seitse")
+      , (28, "kakskümmend kaheksa")
+      , (29, "kakskümmend üheksa")
+      , (30, "kolmkümmend")
+      , (31, "kolmkümmend üks")
+      , (32, "kolmkümmend kaks")
+      , (33, "kolmkümmend kolm")
+      , (34, "kolmkümmend neli")
+      , (35, "kolmkümmend viis")
+      , (36, "kolmkümmend kuus")
+      , (37, "kolmkümmend seitse")
+      , (38, "kolmkümmend kaheksa")
+      , (39, "kolmkümmend üheksa")
+      , (40, "nelikümmend")
+      , (41, "nelikümmend üks")
+      , (42, "nelikümmend kaks")
+      , (43, "nelikümmend kolm")
+      , (44, "nelikümmend neli")
+      , (45, "nelikümmend viis")
+      , (46, "nelikümmend kuus")
+      , (47, "nelikümmend seitse")
+      , (48, "nelikümmend kaheksa")
+      , (49, "nelikümmend üheksa")
+      , (50, "viiskümmend")
+      , (51, "viiskümmend üks")
+      , (52, "viiskümmend kaks")
+      , (53, "viiskümmend kolm")
+      , (54, "viiskümmend neli")
+      , (55, "viiskümmend viis")
+      , (56, "viiskümmend kuus")
+      , (57, "viiskümmend seitse")
+      , (58, "viiskümmend kaheksa")
+      , (59, "viiskümmend üheksa")
+      , (61, "kuuskümmend üks")
+      , (62, "kuuskümmend kaks")
+      , (63, "kuuskümmend kolm")
+      , (64, "kuuskümmend neli")
+      , (65, "kuuskümmend viis")
+      , (66, "kuuskümmend kuus")
+      , (67, "kuuskümmend seitse")
+      , (68, "kuuskümmend kaheksa")
+      , (69, "kuuskümmend üheksa")
+      , (71, "seitsekümmend üks")
+      , (72, "seitsekümmend kaks")
+      , (73, "seitsekümmend kolm")
+      , (74, "seitsekümmend neli")
+      , (75, "seitsekümmend viis")
+      , (76, "seitsekümmend kuus")
+      , (77, "seitsekümmend seitse")
+      , (78, "seitsekümmend kaheksa")
+      , (79, "seitsekümmend üheksa")
+      , (81, "kaheksakümmend üks")
+      , (82, "kaheksakümmend kaks")
+      , (83, "kaheksakümmend kolm")
+      , (84, "kaheksakümmend neli")
+      , (85, "kaheksakümmend viis")
+      , (86, "kaheksakümmend kuus")
+      , (87, "kaheksakümmend seitse")
+      , (88, "kaheksakümmend kaheksa")
+      , (89, "kaheksakümmend üheksa")
+      , (91, "üheksakümmend üks")
+      , (92, "üheksakümmend kaks")
+      , (93, "üheksakümmend kolm")
+      , (94, "üheksakümmend neli")
+      , (95, "üheksakümmend viis")
+      , (96, "üheksakümmend kuus")
+      , (97, "üheksakümmend seitse")
+      , (98, "üheksakümmend kaheksa")
+      , (99, "üheksakümmend üheksa")
+      , (100, "sada")
+      , (101, "sadaüks")
+      , (102, "sadakaks")
+      , (103, "sadakolm")
+      , (104, "sadaneli")
+      , (105, "sadaviis")
+      , (106, "sadakuus")
+      , (107, "sadaseitse")
+      , (108, "sadakaheksa")
+      , (109, "sadaüheksa")
+      , (110, "sadakümme")
+      , (123, "sadakakskümmend kolm")
+      , (200, "kakssada")
+      , (300, "kolmsada")
+      , (321, "kolmsadakakskümmend üks")
+      , (400, "nelisada")
+      , (500, "viissada")
+      , (600, "kuussada")
+      , (700, "seitsesada")
+      , (800, "kaheksasada")
+      , (900, "üheksasada")
+      , (909, "üheksasadaüheksa")
+      , (990, "üheksasadaüheksakümmend")
+      , (999, "üheksasadaüheksakümmend üheksa")
+      , (1000, "tuhat")
+      , (1001, "tuhatüks")
+      , (1008, "tuhatkaheksa")
+      , (1234, "tuhatkakssadakolmkümmend neli")
+      , (2000, "kaks tuhat")
+      , (3000, "kolm tuhat")
+      , (4000, "neli tuhat")
+      , (4321, "neli tuhatkolmsadakakskümmend üks")
+      , (5000, "viis tuhat")
+      , (6000, "kuus tuhat")
+      , (7000, "seitse tuhat")
+      , (8000, "kaheksa tuhat")
+      , (9000, "üheksa tuhat")
+      , (10000, "kümme tuhat")
+      , (12345, "kaksteist tuhatkolmsadanelikümmend viis")
+      , (20000, "kakskümmend tuhat")
+      , (30000, "kolmkümmend tuhat")
+      , (40000, "nelikümmend tuhat")
+      , (50000, "viiskümmend tuhat")
+      , (54321, "viiskümmend neli tuhatkolmsadakakskümmend üks")
+      , (60000, "kuuskümmend tuhat")
+      , (70000, "seitsekümmend tuhat")
+      , (80000, "kaheksakümmend tuhat")
+      , (90000, "üheksakümmend tuhat")
+      , (100000, "sada tuhat")
+      , (123456, "sadakakskümmend kolm tuhatnelisadaviiskümmend kuus")
+      , (200000, "kakssada tuhat")
+      , (300000, "kolmsada tuhat")
+      , (400000, "nelisada tuhat")
+      , (500000, "viissada tuhat")
+      , (600000, "kuussada tuhat")
+      , (654321, "kuussadaviiskümmend neli tuhatkolmsadakakskümmend üks")
+      , (700000, "seitsesada tuhat")
+      , (800000, "kaheksasada tuhat")
+      , (900000, "üheksasada tuhat")
+      , (1000000, "miljon")
+      , (1000001, "miljonüks")
+      , (1234567, "miljonkakssadakolmkümmend neli tuhatviissadakuuskümmend seitse")
+      , (2000000, "kaks miljonit")
+      , (3000000, "kolm miljonit")
+      , (4000000, "neli miljonit")
+      , (5000000, "viis miljonit")
+      , (6000000, "kuus miljonit")
+      , (7000000, "seitse miljonit")
+      , (7654321, "seitse miljonitkuussadaviiskümmend neli tuhatkolmsadakakskümmend üks")
+      , (8000000, "kaheksa miljonit")
+      , (9000000, "üheksa miljonit")
+      , (1000000000, "miljard")
+      , (1000000001, "miljardüks")
+      , (2000000000, "kaks miljard")
+      , (3000000000, "kolm miljard")
+      , (4000000000, "neli miljard")
+      , (5000000000, "viis miljard")
+      , (6000000000, "kuus miljard")
+      , (7000000000, "seitse miljard")
+      , (8000000000, "kaheksa miljard")
+      , (9000000000, "üheksa miljard")
+      , (1000000000000, "triljon")
+      , (1000000000001, "triljonüks")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/FI/TestData.hs b/src-test/Text/Numeral/Language/FI/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/FI/TestData.hs
@@ -0,0 +1,1827 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        fi
+
+[@ISO639-2@]        fin
+
+[@ISO639-3@]        fin
+
+[@Native name@]     suomi
+
+[@English name@]    Finnish
+-}
+
+module Text.Numeral.Language.FI.TestData
+    ( cardinals
+    , ordinals
+    , multiplicatives
+    , multipliers
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Data.Function ( ($) )
+import "base" Prelude     ( Integral, (+) )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Grammar
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+-- Sources:
+--   http://www.marijn.org/everything-is-4/counting-0-to-100/finnish
+--   http://www.languagesandnumbers.com/how-to-count-in-finnish/en/fin/
+--   http://en.wikipedia.org/wiki/Finnish_numerals
+--   http://mylanguages.org/finnish_numbers.php
+--   http://users.jyu.fi/~pamakine/kieli/suomi/numeraalit/numeroten.html
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "singular nominative"
+    , singular $ nominative defaultInflection
+    , [ (0, "nolla")
+      , (1, "yksi")
+      , (2, "kaksi")
+      , (3, "kolme")
+      , (4, "neljä")
+      , (5, "viisi")
+      , (6, "kuusi")
+      , (7, "seitsemän")
+      , (8, "kahdeksan")
+      , (9, "yhdeksän")
+      , (10, "kymmenen")
+      , (11, "yksitoista")
+      , (12, "kaksitoista")
+      , (13, "kolmetoista")
+      , (14, "neljätoista")
+      , (15, "viisitoista")
+      , (16, "kuusitoista")
+      , (17, "seitsemäntoista")
+      , (18, "kahdeksantoista")
+      , (19, "yhdeksäntoista")
+      , (20, "kaksikymmentä")
+      , (21, "kaksikymmentäyksi")
+      , (22, "kaksikymmentäkaksi")
+      , (23, "kaksikymmentäkolme")
+      , (24, "kaksikymmentäneljä")
+      , (25, "kaksikymmentäviisi")
+      , (26, "kaksikymmentäkuusi")
+      , (27, "kaksikymmentäseitsemän")
+      , (28, "kaksikymmentäkahdeksan")
+      , (29, "kaksikymmentäyhdeksän")
+      , (30, "kolmekymmentä")
+      , (31, "kolmekymmentäyksi")
+      , (32, "kolmekymmentäkaksi")
+      , (33, "kolmekymmentäkolme")
+      , (34, "kolmekymmentäneljä")
+      , (35, "kolmekymmentäviisi")
+      , (36, "kolmekymmentäkuusi")
+      , (37, "kolmekymmentäseitsemän")
+      , (38, "kolmekymmentäkahdeksan")
+      , (39, "kolmekymmentäyhdeksän")
+      , (40, "neljäkymmentä")
+      , (41, "neljäkymmentäyksi")
+      , (42, "neljäkymmentäkaksi")
+      , (43, "neljäkymmentäkolme")
+      , (44, "neljäkymmentäneljä")
+      , (45, "neljäkymmentäviisi")
+      , (46, "neljäkymmentäkuusi")
+      , (47, "neljäkymmentäseitsemän")
+      , (48, "neljäkymmentäkahdeksan")
+      , (49, "neljäkymmentäyhdeksän")
+      , (50, "viisikymmentä")
+      , (51, "viisikymmentäyksi")
+      , (52, "viisikymmentäkaksi")
+      , (53, "viisikymmentäkolme")
+      , (54, "viisikymmentäneljä")
+      , (55, "viisikymmentäviisi")
+      , (56, "viisikymmentäkuusi")
+      , (57, "viisikymmentäseitsemän")
+      , (58, "viisikymmentäkahdeksan")
+      , (59, "viisikymmentäyhdeksän")
+      , (60, "kuusikymmentä")
+      , (61, "kuusikymmentäyksi")
+      , (62, "kuusikymmentäkaksi")
+      , (63, "kuusikymmentäkolme")
+      , (64, "kuusikymmentäneljä")
+      , (65, "kuusikymmentäviisi")
+      , (66, "kuusikymmentäkuusi")
+      , (67, "kuusikymmentäseitsemän")
+      , (68, "kuusikymmentäkahdeksan")
+      , (69, "kuusikymmentäyhdeksän")
+      , (70, "seitsemänkymmentä")
+      , (71, "seitsemänkymmentäyksi")
+      , (72, "seitsemänkymmentäkaksi")
+      , (73, "seitsemänkymmentäkolme")
+      , (74, "seitsemänkymmentäneljä")
+      , (75, "seitsemänkymmentäviisi")
+      , (76, "seitsemänkymmentäkuusi")
+      , (77, "seitsemänkymmentäseitsemän")
+      , (78, "seitsemänkymmentäkahdeksan")
+      , (79, "seitsemänkymmentäyhdeksän")
+      , (80, "kahdeksankymmentä")
+      , (81, "kahdeksankymmentäyksi")
+      , (82, "kahdeksankymmentäkaksi")
+      , (83, "kahdeksankymmentäkolme")
+      , (84, "kahdeksankymmentäneljä")
+      , (85, "kahdeksankymmentäviisi")
+      , (86, "kahdeksankymmentäkuusi")
+      , (87, "kahdeksankymmentäseitsemän")
+      , (88, "kahdeksankymmentäkahdeksan")
+      , (89, "kahdeksankymmentäyhdeksän")
+      , (90, "yhdeksänkymmentä")
+      , (91, "yhdeksänkymmentäyksi")
+      , (92, "yhdeksänkymmentäkaksi")
+      , (93, "yhdeksänkymmentäkolme")
+      , (94, "yhdeksänkymmentäneljä")
+      , (95, "yhdeksänkymmentäviisi")
+      , (96, "yhdeksänkymmentäkuusi")
+      , (97, "yhdeksänkymmentäseitsemän")
+      , (98, "yhdeksänkymmentäkahdeksan")
+      , (99, "yhdeksänkymmentäyhdeksän")
+      , (100, "sata")
+      , (101, "satayksi")
+      , (123, "satakaksikymmentäkolme")
+      , (200, "kaksisataa")
+      , (300, "kolmesataa")
+      , (357, "kolmesataaviisikymmentäseitsemän")
+      , (400, "neljäsataa")
+      , (500, "viisisataa")
+      , (567, "viisisataakuusikymmentäseitsemän")
+      , (600, "kuusisataa")
+      , (700, "seitsemänsataa")
+      , (800, "kahdeksansataa")
+      , (900, "yhdeksänsataa")
+      , (999, "yhdeksänsataayhdeksänkymmentäyhdeksän")
+      , (1000, "tuhat")
+      , (1001, "tuhatyksi")
+      , (2000, "kaksituhatta")
+      , (3000, "kolmetuhatta")
+      , (3456, "kolmetuhattaneljäsataaviisikymmentäkuusi")
+      , (3721, "kolmetuhattaseitsemänsataakaksikymmentäyksi")
+      , (4000, "neljätuhatta")
+      , (5000, "viisituhatta")
+      , (6000, "kuusituhatta")
+      , (7000, "seitsemäntuhatta")
+      , (8000, "kahdeksantuhatta")
+      , (9000, "yhdeksäntuhatta")
+      , (10000, "kymmenentuhatta")
+      , (11000, "toistatuhatta")
+      , (12000, "toistakaksituhatta")
+      , (13000, "toistakolmetuhatta")
+      , (dec 5, "satatuhatta")
+      , (2 ⋅ dec 5, "kaksisataatuhatta")
+      , (dec 6, "miljoona")
+      , (dec 6 + 1, "miljoonayksi")
+      , (2 ⋅ dec 6, "kaksimiljoonaa")
+      , (32534756, "kolmekymmentäkaksimiljoonaaviisisataakolmekymmentäneljätuhattaseitsemänsataaviisikymmentäkuusi")
+      , (dec 9, "miljardi")
+      , (2 ⋅ dec 9, "kaksimiljardia")
+      , (3 ⋅ dec 9, "kolmemiljardia")
+      , (dec 12, "biljoona")
+      , (3 ⋅ dec 12, "kolmebiljoonaa")
+      ]
+    )
+  , ( "singular accusative"
+    , singular $ accusative defaultInflection
+    , [ (0, "nolla")
+      , (1, "yksi")
+      , (2, "kaksi")
+      , (3, "kolme")
+      , (4, "neljä")
+      , (5, "viisi")
+      , (6, "kuusi")
+      , (7, "seitsemän")
+      , (8, "kahdeksan")
+      , (9, "yhdeksän")
+      , (10, "kymmenen")
+      , (11, "yksitoista")
+      , (12, "kaksitoista")
+      , (13, "kolmetoista")
+      , (14, "neljätoista")
+      , (15, "viisitoista")
+      , (16, "kuusitoista")
+      , (17, "seitsemäntoista")
+      , (18, "kahdeksantoista")
+      , (19, "yhdeksäntoista")
+      , (20, "kaksikymmentä")
+      , (21, "kaksikymmentäyksi")
+      , (100, "sata")
+      , (1000, "tuhat")
+      ]
+    )
+  , ( "singular genitive"
+    , singular $ genitive defaultInflection
+    , [ (0, "nollan")
+      , (1, "yhden")
+      , (2, "kahden")
+      , (3, "kolmen")
+      , (4, "neljän")
+      , (5, "viiden")
+      , (6, "kuuden")
+      , (7, "seitsemän")
+      , (8, "kahdeksan")
+      , (9, "yhdeksän")
+      , (10, "kymmenen")
+      , (11, "yhdentoista")
+      , (12, "kahdentoista")
+      , (13, "kolmentoista")
+      , (14, "neljäntoista")
+      , (15, "viidentoista")
+      , (16, "kuudentoista")
+      , (17, "seitsemäntoista")
+      , (18, "kahdeksantoista")
+      , (19, "yhdeksäntoista")
+      , (20, "kahdenkymmenen")
+      , (21, "kahdenkymmenenyhden")
+      , (100, "sadan")
+      , (357, "kolmensadanviidenkymmenenseitsemän")
+      , (1000, "tuhannen")
+      ]
+    )
+  , ( "singular partitive"
+    , singular $ partitive defaultInflection
+    , [ (0, "nollaa")
+      , (1, "yhtä")
+      , (2, "kahta")
+      , (3, "kolmea")
+      , (4, "neljää")
+      , (5, "viittä")
+      , (6, "kuutta")
+      , (7, "seitsemää")
+      , (8, "kahdeksaa")
+      , (9, "yhdeksää")
+      , (10, "kymmentä")
+      , (11, "yhtätoista")
+      , (12, "kahtatoista")
+      , (13, "kolmeatoista")
+      , (14, "neljäätoista")
+      , (15, "viittätoista")
+      , (16, "kuuttatoista")
+      , (17, "seitsemäätoista")
+      , (18, "kahdeksaatoista")
+      , (19, "yhdeksäätoista")
+      , (20, "kahtakymmentä")
+      , (21, "kahtakymmentäyhtä")
+      , (100, "sataa")
+      , (357, "kolmeasataaviittäkymmentäseitsemää")
+      , (1000, "tuhatta")
+      ]
+    )
+  , ( "singular essive"
+    , singular $ essive defaultInflection
+    , [ (0, "nollana")
+      , (1, "yhtenä")
+      , (2, "kahtena")
+      , (3, "kolmena")
+      , (4, "neljänä")
+      , (5, "viitenä")
+      , (6, "kuutena")
+      , (7, "seitsemänä")
+      , (8, "kahdeksana")
+      , (9, "yhdeksänä")
+      , (10, "kymmenenä")
+      , (11, "yhtenätoista")
+      , (12, "kahtenatoista")
+      , (13, "kolmenatoista")
+      , (14, "neljänätoista")
+      , (15, "viitenätoista")
+      , (16, "kuutenatoista")
+      , (17, "seitsemänätoista")
+      , (18, "kahdeksanatoista")
+      , (19, "yhdeksänätoista")
+      , (20, "kahtenakymmenenä")
+      , (21, "kahdessakymmenessäyhdessä")
+      , (100, "satana")
+      , (357, "kolmenasatanaviitenäkymmenenäseitsemänä")
+      , (1000, "tuhantena")
+      ]
+    )
+  , ( "singular translative"
+    , singular $ translative defaultInflection
+    , [ (0, "nollaksi")
+      , (1, "yhdeksi")
+      , (2, "kahdeksi")
+      , (3, "kolmeksi")
+      , (4, "neljäksi")
+      , (5, "viideksi")
+      , (6, "kuudeksi")
+      , (7, "seitsemäksi")
+      , (8, "kahdeksaksi")
+      , (9, "yhdeksäksi")
+      , (10, "kymmeneksi")
+      , (11, "yhdeksitoista")
+      , (12, "kahdeksitoista")
+      , (13, "kolmeksitoista")
+      , (14, "neljäksitoista")
+      , (15, "viideksitoista")
+      , (16, "kuudeksitoista")
+      , (17, "seitsemäksitoista")
+      , (18, "kahdeksaksitoista")
+      , (19, "yhdeksäksitoista")
+      , (20, "kahdeksikymmeneksi")
+      , (21, "kahdeksikymmeneksiyhdeksi")
+      , (100, "sadaksi")
+      , (1000, "tuhanneksi")
+      ]
+    )
+  , ( "singular locative inessive"
+    , singular $ locativeInessive defaultInflection
+    , [ (0, "nollassa")
+      , (1, "yhdessä")
+      , (2, "kahdessa")
+      , (3, "kolmessa")
+      , (4, "neljässä")
+      , (5, "viidessä")
+      , (6, "kuudessa")
+      , (7, "seitsemässä")
+      , (8, "kahdeksassa")
+      , (9, "yhdeksässä")
+      , (10, "kymmenessä")
+      , (11, "yhdessätoista")
+      , (12, "kahdessatoista")
+      , (13, "kolmessatoista")
+      , (14, "neljässätoista")
+      , (15, "viidessätoista")
+      , (16, "kuudessatoista")
+      , (17, "seitsemässätoista")
+      , (18, "kahdeksassatoista")
+      , (19, "yhdeksässätoista")
+      , (20, "kahdessakymmenessä")
+      , (21, "kahdessakymmenessäyhdessä")
+      , (100, "sadassa")
+      , (1000, "tuhannessa")
+      ]
+    )
+  , ( "singular locative elative"
+    , singular $ locativeElative defaultInflection
+    , [ (0, "nollasta")
+      , (1, "yhdestä")
+      , (2, "kahdesta")
+      , (3, "kolmesta")
+      , (4, "neljästä")
+      , (5, "viidestä")
+      , (6, "kuudesta")
+      , (7, "seitsemästä")
+      , (8, "kahdeksasta")
+      , (9, "yhdeksästä")
+      , (10, "kymmenestä")
+      , (11, "yhdestätoista")
+      , (12, "kahdestatoista")
+      , (13, "kolmestatoista")
+      , (14, "neljästätoista")
+      , (15, "viidestätoista")
+      , (16, "kuudestatoista")
+      , (17, "seitsemästätoista")
+      , (18, "kahdeksastatoista")
+      , (19, "yhdeksästätoista")
+      , (20, "kahdestakymmenestä")
+      , (21, "kahdestakymmenestäyhdestä")
+      , (100, "sadasta")
+      , (1000, "tuhannesta")
+      ]
+    )
+  , ( "singular locative illative"
+    ,  singular $ locativeIllative defaultInflection
+    , [ (0, "nollaan")
+      , (1, "yhteen")
+      , (2, "kahteen")
+      , (3, "kolmeen")
+      , (4, "neljään")
+      , (5, "viiteen")
+      , (6, "kuuteen")
+      , (7, "seitsemään")
+      , (8, "kahdeksaan")
+      , (9, "yhdeksään")
+      , (10, "kymmeneen")
+      , (11, "yhteentoista")
+      , (12, "kahteentoista")
+      , (13, "kolmeentoista")
+      , (14, "neljääntoista")
+      , (15, "viiteentoista")
+      , (16, "kuuteentoista")
+      , (17, "seitsemääntoista")
+      , (18, "kahdeksaantoista")
+      , (19, "yhdeksääntoista")
+      , (20, "kahteenkymmeneen")
+      , (21, "kahteenkymmeneenyhteen")
+      , (100, "sataan")
+      , (1000, "tuhanteen")
+      ]
+    )
+  , ( "singular locative adessive"
+    , singular $ locativeAdessive defaultInflection
+    , [ (0, "nollalla")
+      , (1, "yhdellä")
+      , (2, "kahdella")
+      , (3, "kolmella")
+      , (4, "neljällä")
+      , (5, "viidellä")
+      , (6, "kuudella")
+      , (7, "seitsemällä")
+      , (8, "kahdeksalla")
+      , (9, "yhdeksällä")
+      , (10, "kymmenellä")
+      , (11, "yhdellätoista")
+      , (12, "kahdellatoista")
+      , (13, "kolmellatoista")
+      , (14, "neljällätoista")
+      , (15, "viidellätoista")
+      , (16, "kuudellatoista")
+      , (17, "seitsemällätoista")
+      , (18, "kahdeksallatoista")
+      , (19, "yhdeksällätoista")
+      , (20, "kahdellakymmenellä")
+      , (21, "kahdellakymmenelläyhdellä")
+      , (100, "sadalla")
+      , (1000, "tuhannella")
+      ]
+    )
+  , ( "singular locative ablative"
+    , singular $ locativeAblative defaultInflection
+    , [ (0, "nollalta")
+      , (1, "yhdeltä")
+      , (2, "kahdelta")
+      , (3, "kolmelta")
+      , (4, "neljältä")
+      , (5, "viideltä")
+      , (6, "kuudelta")
+      , (7, "seitsemältä")
+      , (8, "kahdeksalta")
+      , (9, "yhdeksältä")
+      , (10, "kymmeneltä")
+      , (11, "yhdeltätoista")
+      , (12, "kahdeltatoista")
+      , (13, "kolmeltatoista")
+      , (14, "neljältätoista")
+      , (15, "viideltätoista")
+      , (16, "kuudeltatoista")
+      , (17, "seitsemältätoista")
+      , (18, "kahdeksaltatoista")
+      , (19, "yhdeksältätoista")
+      , (20, "kahdeltakymmeneltä")
+      , (21, "kahdeltakymmeneltäyhdeltä")
+      , (100, "sadalta")
+      , (1000, "tuhannelta")
+      ]
+    )
+  , ( "singular locative allative"
+    , singular $ locativeAllative defaultInflection
+    , [ (0, "nollalle")
+      , (1, "yhdelle")
+      , (2, "kahdelle")
+      , (3, "kolmelle")
+      , (4, "neljälle")
+      , (5, "viidelle")
+      , (6, "kuudelle")
+      , (7, "seitsemälle")
+      , (8, "kahdeksalle")
+      , (9, "yhdeksälle")
+      , (10, "kymmenelle")
+      , (11, "yhdelletoista")
+      , (12, "kahdelletoista")
+      , (13, "kolmelletoista")
+      , (14, "neljälletoista")
+      , (15, "viidelletoista")
+      , (16, "kuudelletoista")
+      , (17, "seitsemälletoista")
+      , (18, "kahdeksalletoista")
+      , (19, "yhdeksälletoista")
+      , (20, "kahdellekymmenelle")
+      , (21, "kahdellekymmenelleyhdelle")
+      , (100, "sadalle")
+      , (1000, "tuhannelle")
+      ]
+    )
+  , ( "singular abessive"
+    , singular $ abessive defaultInflection
+    , [ (0, "nollatta")
+      , (1, "yhdettä")
+      , (2, "kahdetta")
+      , (3, "kolmetta")
+      , (4, "neljättä")
+      , (5, "viidettä")
+      , (6, "kuudetta")
+      , (7, "seitsemättä")
+      , (8, "kahdeksatta")
+      , (9, "yhdeksättä")
+      , (10, "kymmenettä")
+      , (11, "yhdettätoista")
+      , (12, "kahdettatoista")
+      , (13, "kolmettatoista")
+      , (14, "neljättätoista")
+      , (15, "viidettätoista")
+      , (16, "kuudettatoista")
+      , (17, "seitsemättätoista")
+      , (18, "kahdeksattatoista")
+      , (19, "yhdeksättätoista")
+      , (20, "kahdettakymmenettä")
+      , (21, "kahdettakymmenettäyhdettä")
+      , (100, "sadatta")
+      , (1000, "tuhannetta")
+      ]
+    )
+  , ( "singular super essive"
+    , singular $ superEssive defaultInflection
+    , [ (1, "yhtäällä")
+      , (2, "kahtaalla")
+      ]
+    )
+  , ( "singular delative"
+    , singular $ delative defaultInflection
+    , [ (1, "yhtäältä")
+      , (2, "kahtaalta")
+      ]
+    )
+  , ( "singular sublative"
+    , singular $ sublative defaultInflection
+    , [ (1, "yhtäälle")
+      , (2, "kahtaalle")
+      ]
+    )
+  , ( "singular lative"
+    , singular $ lative defaultInflection
+    , [ (1, "yhä")
+      , (2, "kahtia")
+      , (3, "kolmia")
+      ]
+    )
+  , ( "singular multiplicative"
+    , singular $ multiplicative defaultInflection
+    , [ (1, "yhdesti")
+      , (2, "kahdesti")
+      , (3, "kolmesti")
+      ]
+    )
+  , ( "plural nominative"
+    , plural $ nominative defaultInflection
+    , [ (0, "nollat")
+      , (1, "yhdet")
+      , (2, "kahdet")
+      , (3, "kolmet")
+      , (4, "neljät")
+      , (5, "viidet")
+      , (6, "kuudet")
+      , (7, "seitsemät")
+      , (8, "kahdeksat")
+      , (9, "yhdeksät")
+      , (10, "kymmenet")
+      , (11, "yhdettoista")
+      , (12, "kahdettoista")
+      , (13, "kolmettoista")
+      , (14, "neljättoista")
+      , (15, "viidettoista")
+      , (16, "kuudettoista")
+      , (17, "seitsemättoista")
+      , (18, "kahdeksattoista")
+      , (19, "yhdeksättoista")
+      , (20, "kahdetkymmenet")
+      , (21, "kahdetkymmenetyhdet")
+      , (100, "sadat")
+      , (1000, "tuhannet")
+      ]
+    )
+  , ( "plural accusative"
+    , plural $ accusative defaultInflection
+    , [ (0, "nollat")
+      , (1, "yhdet")
+      , (2, "kahdet")
+      , (3, "kolmet")
+      , (4, "neljät")
+      , (5, "viidet")
+      , (6, "kuudet")
+      , (7, "seitsemät")
+      , (8, "kahdeksat")
+      , (9, "yhdeksät")
+      , (10, "kymmenet")
+      , (11, "yhdettoista")
+      , (12, "kahdettoista")
+      , (13, "kolmettoista")
+      , (14, "neljättoista")
+      , (15, "viidettoista")
+      , (16, "kuudettoista")
+      , (17, "seitsemättoista")
+      , (18, "kahdeksattoista")
+      , (19, "yhdeksättoista")
+      , (20, "kahdetkymmenet")
+      , (21, "kahdetkymmenetyhdet")
+      , (100, "sadat")
+      , (1000, "tuhannet")
+      ]
+    )
+  , ( "plural genitive"
+    , plural $ genitive defaultInflection
+    , [ (0, "nollien")
+      , (1, "yksien")
+      , (2, "kaksien")
+      , (3, "kolmien")
+      , (4, "neljien")
+      , (5, "viisien")
+      , (6, "kuusien")
+      , (7, "seitsemien")
+      , (8, "kahdeksien")
+      , (9, "yhdeksien")
+      , (10, "kymmenien")
+      , (11, "yksientoista")
+      , (12, "kaksientoista")
+      , (13, "kolmientoista")
+      , (14, "neljientoista")
+      , (15, "viisientoista")
+      , (16, "kuusientoista")
+      , (17, "seitsemientoista")
+      , (18, "kahdeksientoista")
+      , (19, "yhdeksientoista")
+      , (20, "kaksienkymmenien")
+      , (21, "kaksienkymmenienyksien")
+      , (100, "satojen")
+      , (1000, "tuhansien")
+      ]
+    )
+  , ( "plural partitive"
+    , plural $ partitive defaultInflection
+    , [ (0, "nollia")
+      , (1, "yksiä")
+      , (2, "kaksia")
+      , (3, "kolmia")
+      , (4, "neljiä")
+      , (5, "viisiä")
+      , (6, "kuusia")
+      , (7, "seitsemiä")
+      , (8, "kahdeksia")
+      , (9, "yhdeksiä")
+      , (10, "kymmeniä")
+      , (11, "yksiätoista")
+      , (12, "kaksiatoista")
+      , (13, "kolmiatoista")
+      , (14, "neljiätoista")
+      , (15, "viittätoista")
+      , (16, "kuuttatoista")
+      , (17, "seitsemiätoista")
+      , (18, "kahdeksiatoista")
+      , (19, "yhdeksiätoista")
+      , (20, "kaksiakymmeniä")
+      , (21, "kaksiakymmeniäyksiä")
+      , (100, "satoja")
+      , (1000, "tuhansia")
+      ]
+    )
+  , ( "plural essive"
+    , plural $ essive defaultInflection
+    , [ (0, "nollina")
+      , (1, "yksinä")
+      , (2, "kaksina")
+      , (3, "kolmina")
+      , (4, "neljinä")
+      , (5, "viisinä")
+      , (6, "kuusina")
+      , (7, "seitseminä")
+      , (8, "kahdeksina")
+      , (9, "yhdeksinä")
+      , (10, "kymmeninä")
+      , (11, "yksinätoista")
+      , (12, "kaksinatoista")
+      , (13, "kolminatoista")
+      , (14, "neljinätoista")
+      , (15, "viitenätoista")
+      , (16, "kuutenatoista")
+      , (17, "seitseminätoista")
+      , (18, "kahdeksinatoista")
+      , (19, "yhdeksinätoista")
+      , (20, "kaksinakymmeninä")
+      , (21, "kaksinakymmeninäyksinä")
+      , (100, "satoina")
+      , (1000, "tuhansina")
+      ]
+    )
+  , ( "plural translative"
+    , plural $ translative defaultInflection
+    , [ (0, "nolliksi")
+      , (1, "yksiksi")
+      , (2, "kaksiksi")
+      , (3, "kolmiksi")
+      , (4, "neljiksi")
+      , (5, "viisiksi")
+      , (6, "kuusiksi")
+      , (7, "seitsemiksi")
+      , (8, "kahdeksiksi")
+      , (9, "yhdeksiksi")
+      , (10, "kymmeniksi")
+      , (11, "yksiksitoista")
+      , (12, "kaksiksitoista")
+      , (13, "kolmiksitoista")
+      , (14, "neljiksitoista")
+      , (15, "viideksitoista")
+      , (16, "kuudeksitoista")
+      , (17, "seitsemiksitoista")
+      , (18, "kahdeksiksitoista")
+      , (19, "yhdeksiksitoista")
+      , (20, "kaksiksikymmeniksi")
+      , (21, "kaksiksikymmeniksiyksiksi")
+      , (100, "sadoiksi")
+      , (1000, "tuhansiksi")
+      ]
+    )
+  , ( "plural locative inessive"
+    , plural $ locativeInessive defaultInflection
+    , [ (0, "nollissa")
+      , (1, "yksissä")
+      , (2, "kaksissa")
+      , (3, "kolmissa")
+      , (4, "neljissä")
+      , (5, "viisissä")
+      , (6, "kuusissa")
+      , (7, "seitsemissä")
+      , (8, "kahdeksissa")
+      , (9, "yhdeksissä")
+      , (10, "kymmenissä")
+      , (11, "yksissätoista")
+      , (12, "kaksissatoista")
+      , (13, "kolmissatoista")
+      , (14, "neljissätoista")
+      , (15, "viidessätoista")
+      , (16, "kuudessatoista")
+      , (17, "seitsemissätoista")
+      , (18, "kahdeksissatoista")
+      , (19, "yhdeksissätoista")
+      , (20, "kaksissakymmenissä")
+      , (21, "kaksissakymmenissäyksissä")
+      , (100, "sadoissa")
+      , (1000, "tuhansissa")
+      ]
+    )
+  , ( "plural locative elative"
+    , plural $ locativeElative defaultInflection
+    , [ (0, "nollista")
+      , (1, "yksistä")
+      , (2, "kaksista")
+      , (3, "kolmista")
+      , (4, "neljistä")
+      , (5, "viisistä")
+      , (6, "kuusista")
+      , (7, "seitsemistä")
+      , (8, "kahdeksista")
+      , (9, "yhdeksistä")
+      , (10, "kymmenistä")
+      , (11, "yksistätoista")
+      , (12, "kaksistatoista")
+      , (13, "kolmistatoista")
+      , (14, "neljistätoista")
+      , (15, "viidestätoista")
+      , (16, "kuudestatoista")
+      , (17, "seitsemistätoista")
+      , (18, "kahdeksistatoista")
+      , (19, "yhdeksistätoista")
+      , (20, "kaksistakymmenistä")
+      , (21, "kaksistakymmenistäyksistä")
+      , (100, "sadoista")
+      , (1000, "tuhansista")
+      ]
+    )
+  , ( "plural locative illative"
+    , plural $ locativeIllative defaultInflection
+    , [ (0, "nolliin")
+      , (1, "yksiin")
+      , (2, "kaksiin")
+      , (3, "kolmiin")
+      , (4, "neljiin")
+      , (5, "viisiin")
+      , (6, "kuusiin")
+      , (7, "seitsemiin")
+      , (8, "kahdeksiin")
+      , (9, "yhdeksiin")
+      , (10, "kymmeniin")
+      , (11, "yksiintoista")
+      , (12, "kaksiintoista")
+      , (13, "kolmiintoista")
+      , (14, "neljiintoista")
+      , (15, "viiteentoista")
+      , (16, "kuuteentoista")
+      , (17, "seitsemiintoista")
+      , (18, "kahdeksiintoista")
+      , (19, "yhdeksiintoista")
+      , (20, "kaksiinkymmeniin")
+      , (21, "kaksiinkymmeniinyksiin")
+      , (100, "satoihin")
+      , (1000, "tuhansiin")
+      ]
+    )
+  , ( "plural locative adessive"
+    , plural $ locativeAdessive defaultInflection
+    , [ (0, "nollilla")
+      , (1, "yksillä")
+      , (2, "kaksilla")
+      , (3, "kolmilla")
+      , (4, "neljillä")
+      , (5, "viisillä")
+      , (6, "kuusilla")
+      , (7, "seitsemillä")
+      , (8, "kahdeksilla")
+      , (9, "yhdeksillä")
+      , (10, "kymmenillä")
+      , (11, "yksillätoista")
+      , (12, "kaksillatoista")
+      , (13, "kolmillatoista")
+      , (14, "neljillätoista")
+      , (15, "viidellätoista")
+      , (16, "kuudellatoista")
+      , (17, "seitsemillätoista")
+      , (18, "kahdeksillatoista")
+      , (19, "yhdeksillätoista")
+      , (20, "kaksillakymmenillä")
+      , (21, "kaksillakymmenilläyksillä")
+      , (100, "sadoilla")
+      , (1000, "tuhansilla")
+      ]
+    )
+  , ( "plural locative ablative"
+    , plural $ locativeAblative defaultInflection
+    , [ (0, "nollilta")
+      , (1, "yksiltä")
+      , (2, "kaksilta")
+      , (3, "kolmilta")
+      , (4, "neljiltä")
+      , (5, "viisiltä")
+      , (6, "kuusilta")
+      , (7, "seitsemiltä")
+      , (8, "kahdeksilta")
+      , (9, "yhdeksiltä")
+      , (10, "kymmeniltä")
+      , (11, "yksiltätoista")
+      , (12, "kaksiltatoista")
+      , (13, "kolmiltatoista")
+      , (14, "neljiltätoista")
+      , (15, "viideltätoista")
+      , (16, "kuudeltatoista")
+      , (17, "seitsemiltätoista")
+      , (18, "kahdeksiltatoista")
+      , (19, "yhdeksiltätoista")
+      , (20, "kaksiltakymmeniltä")
+      , (21, "kaksiltakymeniltäyksiltä")
+      , (100, "sadoilta")
+      , (1000, "tuhansilta")
+      ]
+    )
+  , ( "plural locative allative"
+    , plural $ locativeAllative defaultInflection
+    , [ (0, "nollille")
+      , (1, "yksille")
+      , (2, "kaksille")
+      , (3, "kolmille")
+      , (4, "neljille")
+      , (5, "viisille")
+      , (6, "kuusille")
+      , (7, "seitsemille")
+      , (8, "kahdeksille")
+      , (9, "yhdeksille")
+      , (10, "kymmenille")
+      , (11, "yksilletoista")
+      , (12, "kaksilletoista")
+      , (13, "kolmilletoista")
+      , (14, "neljilletoista")
+      , (15, "viidelletoista")
+      , (16, "kuudelletoista")
+      , (17, "seitsemilletoista")
+      , (18, "kahdeksilletoista")
+      , (19, "yhdeksilletoista")
+      , (20, "kaksillekymmenille")
+      , (21, "kaksillekymmenilleyksille")
+      , (100, "sadoille")
+      , (1000, "tuhansille")
+      ]
+    )
+  , ( "plural abessive"
+    , plural $ abessive defaultInflection
+    , [ (0, "nollitta")
+      , (1, "yksittä")
+      , (2, "kaksitta")
+      , (3, "kolmitta")
+      , (4, "neljittä")
+      , (5, "viisittä")
+      , (6, "kuusitta")
+      , (7, "seitsemittä")
+      , (8, "kahdeksitta")
+      , (9, "yhdeksittä")
+      , (10, "kymmenittä")
+      , (11, "yksittätoista")
+      , (12, "kaksittatoista")
+      , (13, "kolmittatoista")
+      , (14, "neljittätoista")
+      , (15, "viidettätoista")
+      , (16, "kuudettatoista")
+      , (17, "seitsemittätoista")
+      , (18, "kahdeksittatoista")
+      , (19, "yhdeksittätoista")
+      , (20, "kaksittakymmenittä")
+      , (21, "kaksittakymmenittäyksittä")
+      , (100, "sadoitta")
+      , (1000, "tuhansitta")
+      ]
+    )
+  , ( "plural comitative"
+    , plural $ comitative defaultInflection
+    , [ (0, "nolline")
+      , (1, "yksine")
+      , (2, "kaksine")
+      , (3, "kolmine")
+      , (4, "neljine")
+      , (5, "viisine")
+      , (6, "kuusine")
+      , (7, "seitsemine")
+      , (8, "kahdeksine")
+      , (9, "yhdeksine")
+      , (10, "kymmenine")
+      , (11, "yksinetoista")
+      , (12, "kaksinetoista")
+      , (13, "kolminetoista")
+      , (14, "neljinetoista")
+      , (15, "viisinetoista")
+      , (16, "kuusinetoista")
+      , (17, "seitseminetoista")
+      , (18, "kahdeksinetoista")
+      , (19, "yhdeksinetoista")
+      , (20, "kaksinekymmenine")
+      , (21, "kaksinekymmenineyksine")
+      , (100, "satoine")
+      , (1000, "tuhansine")
+      ]
+    )
+  , ( "plural instructive"
+    , plural $ instructive defaultInflection
+    , [ (0, "nollin")
+      , (1, "yksin")
+      , (2, "kaksin")
+      , (3, "kolmin")
+      , (4, "neljin")
+      , (5, "viisin")
+      , (6, "kuusin")
+      , (7, "seitsemin")
+      , (8, "kahdeksin")
+      , (9, "yhdeksin")
+      , (10, "kymmenin")
+      , (11, "yksintoista")
+      , (12, "kaksintoista")
+      , (13, "kolmintoista")
+      , (14, "neljintoista")
+      , (15, "viisintoista")
+      , (16, "kuusintoista")
+      , (17, "seitsemintoista")
+      , (18, "kahdeksintoista")
+      , (19, "yhdeksintoista")
+      , (20, "kaksinkymmenin")
+      , (21, "kaksinkymmeninyksin")
+      , (100, "sadoin")
+      , (1000, "tuhansin")
+      ]
+    )
+  ]
+
+ordinals ∷ (Integral i) ⇒ TestData i
+ordinals =
+  [ ( "singular nominative"
+    , singular $ nominative defaultInflection
+    , [ (0, "nollas")
+      , (1, "ensimmäinen")
+      , (2, "toinen")
+      , (3, "kolmas")
+      , (4, "neljäs")
+      , (5, "viides")
+      , (6, "kuudes")
+      , (7, "seitsemäs")
+      , (8, "kahdeksas")
+      , (9, "yhdeksäs")
+      , (10, "kymmenes")
+      , (11, "yhdestoista")
+      , (12, "kahdestoista")
+      , (13, "kolmastoista")
+      , (14, "neljästoista")
+      , (15, "viidestoista")
+      , (16, "kuudestoista")
+      , (17, "seitsemästoista")
+      , (18, "kahdeksastoista")
+      , (19, "yhdeksästoista")
+      , (20, "kahdeskymmenes")
+      , (21, "kahdeskymmenesensimmäinen") -- also kahdeskymmenesyhdes
+      , (22, "kahdeskymmenestoinen") -- also kahdeskymmeneskahdes
+      , (23, "kahdeskymmeneskolmas")
+      , (24, "kahdeskymmenesneljäs")
+      , (25, "kahdeskymmenesviides")
+      , (26, "kahdeskymmeneskuudes")
+      , (27, "kahdeskymmenesseitsemäs")
+      , (28, "kahdeskymmeneskahdeksas")
+      , (29, "kahdeskymmenesyhdeksäs")
+      , (30, "kolmaskymmenes")
+      , (40, "neljäskymmenes")
+      , (50, "viideskymmenes")
+      , (60, "kuudeskymmenes")
+      , (70, "seitsemäskymmenes")
+      , (80, "kahdeksaskymmenes")
+      , (90, "yhdeksäskymmenes")
+      , (100, "sadas")
+      , (101, "sadasensimmäinen")
+      , (357, "kolmassadasviideskymmenesseitsemäs")
+      , (1000, "tuhannes")
+      , (1001, "tuhannesensimmäinen")
+      , (3721, "kolmastuhannesseitsemässadaskahdeskymmenesensimmäinen")
+      ]
+    )
+  , ( "singular accusative"
+    , singular $ accusative defaultInflection
+    , [ (0, "nollas")
+      , (1, "ensimmäinen")
+      , (2, "toinen")
+      , (3, "kolmas")
+      , (4, "neljäs")
+      , (5, "viides")
+      , (6, "kuudes")
+      , (7, "seitsemäs")
+      , (8, "kahdeksas")
+      , (9, "yhdeksäs")
+      , (10, "kymmenes")
+      , (11, "yhdestoista")
+      , (12, "kahdestoista")
+      , (13, "kolmastoista")
+      , (14, "neljästoista")
+      , (15, "viidestoista")
+      , (16, "kuudestoista")
+      , (17, "seitsemästoista")
+      , (18, "kahdeksastoista")
+      , (19, "yhdeksästoista")
+      , (20, "kahdeskymmenes")
+      , (21, "kahdeskymmenesensimmäinen")
+      , (100, "sadas")
+      , (1000, "tuhannes")
+      ]
+    )
+  , ( "singular genitive"
+    , singular $ genitive defaultInflection
+    , [ (0, "nollannen")
+      , (1, "ensimmäisen")
+      , (2, "toisen")
+      , (3, "kolmannen")
+      , (4, "neljännen")
+      , (5, "viidennen")
+      , (6, "kuudennen")
+      , (7, "seitsemännen")
+      , (8, "kahdeksannen")
+      , (9, "yhdeksännen")
+      , (10, "kymmenennen")
+      , (11, "yhdennentoista")
+      , (12, "kahdennentoista")
+      , (13, "kolmannentoista")
+      , (14, "neljännentoista")
+      , (15, "viidennentoista")
+      , (16, "kuudennentoista")
+      , (17, "seitsemännentoista")
+      , (18, "kahdeksannentoista")
+      , (19, "yhdeksännentoista")
+      , (20, "kahdennenkymmenennen")
+      , (21, "kahdennenkymmenennenensimmäisen")
+      , (100, "sadannen")
+      , (357, "kolmannensadannenviidennenkymmenennenseitsemännen")
+      , (1000, "tuhannennen")
+      ]
+    )
+  , ( "singular partitive"
+    , singular $ partitive defaultInflection
+    , [ (0, "nollatta")
+      , (1, "ensimmäistä")
+      , (2, "toista")
+      , (3, "kolmatta")
+      , (4, "neljättä")
+      , (5, "viidettä")
+      , (6, "kuudetta")
+      , (7, "seitsemättä")
+      , (8, "kahdeksatta")
+      , (9, "yhdeksättä")
+      , (10, "kymmenettä")
+      , (11, "yhdettätoista")
+      , (12, "kahdettatoista")
+      , (13, "kolmattatoista")
+      , (14, "neljättätoista")
+      , (15, "viidettätoista")
+      , (16, "kuudettatoista")
+      , (17, "seitsemättätoista")
+      , (18, "kahdeksattatoista")
+      , (19, "yhdeksättätoista")
+      , (20, "kahdettakymmenettä")
+      , (21, "kahdettakymmenettäensimmäistä")
+      , (100, "sadatta")
+      , (357, "kolmattasadattaviidettäkymmenettäseitsemätta")
+      , (1000, "tuhannetta")
+      ]
+    )
+  , ( "singular essive"
+    , singular $ essive defaultInflection
+    , [ (0, "nollantena")
+      , (1, "ensimmmäisenä")
+      , (2, "toisena")
+      , (3, "kolmantena")
+      , (4, "neljäntenä")
+      , (5, "viidentenä")
+      , (6, "kuudentena")
+      , (7, "seitsemäntenä")
+      , (8, "kahdeksantena")
+      , (9, "yhdeksäntenä")
+      , (10, "kymmenentenä")
+      , (11, "yhdennessätoista")
+      , (12, "kahdentenatoista")
+      , (13, "kolmantenatoista")
+      , (14, "neljäntenätoista")
+      , (15, "viidentenätoista")
+      , (16, "kuudentenatoista")
+      , (17, "seitsemäntenätoista")
+      , (18, "kahdeksantenatoista")
+      , (19, "yhdeksäntenätoista")
+      , (20, "kahdentenakymmenentenä")
+      , (21, "kahdentenakymmenentenäensimmäisenä")
+      , (100, "sadantena")
+      , (357, "kolmantenasadantenaviidentenäkymmenentenäseitsemäntenä")
+      , (1000, "tuhannentena")
+      ]
+    )
+  , ( "singular translative"
+    , singular $ translative defaultInflection
+    , [ (0, "nollanneksi")
+      , (1, "ensimmäiseksi")
+      , (2, "toiseksi")
+      , (3, "kolmanneksi")
+      , (4, "neljänneksi")
+      , (5, "viidenneksi")
+      , (6, "kuudenneksi")
+      , (7, "seitsemänneksi")
+      , (8, "kahdeksanneksi")
+      , (9, "yhdeksänneksi")
+      , (10, "kymmenenneksi")
+      , (11, "yhdenneksitoista")
+      , (12, "kahdenneksitoista")
+      , (13, "kolmanneksitoista")
+      , (14, "neljänneksitoista")
+      , (15, "viidenneksitoista")
+      , (16, "kuudenneksitoista")
+      , (17, "seitsemänneksitoista")
+      , (18, "kahdenksanneksitoista")
+      , (19, "yhdeksänneksitoista")
+      , (20, "kahdenneksikymmenenneksi")
+      , (21, "kahdenneksikymmenenneksiensimmäiseksi")
+      , (100, "sadanneksi")
+      , (1000, "tuhannenneksi")
+      ]
+    )
+  , ( "singular locative inessive"
+    , singular $ locativeInessive defaultInflection
+    , [ (0, "nollannessa")
+      , (1, "ensimmäisessä")
+      , (2, "toisessa")
+      , (3, "kolmannessa")
+      , (4, "neljännessä")
+      , (5, "viidennessä")
+      , (6, "kuudennessa")
+      , (7, "seitsemännessä")
+      , (8, "kahdeksannessa")
+      , (9, "yhdeksännessä")
+      , (10, "kymmenennessä")
+      , (11, "yhdennessätoista")
+      , (12, "kahdennessatoista")
+      , (13, "kolmannessatoista")
+      , (14, "neljännessätoista")
+      , (15, "viidennessätoista")
+      , (16, "kuudennessatoista")
+      , (17, "seitsemännessätoista")
+      , (18, "kahdeksannessatoista")
+      , (19, "yhdeksännessätoista")
+      , (20, "kahdennessakymmenennessä")
+      , (21, "kahdennessakymmenennessäensimmäisessä")
+      , (100, "sadannessa")
+      , (1000, "tuhannennessa")
+      ]
+    )
+  , ( "singular locative elative"
+    , singular $ locativeElative defaultInflection
+    , [ (0, "nollannesta")
+      , (1, "ensimmäisestä")
+      , (2, "toisesta")
+      , (3, "kolmannesta")
+      , (4, "neljännestä")
+      , (5, "viidennestä")
+      , (6, "kuudennesta")
+      , (7, "seitsemännestä")
+      , (8, "kahdeksannesta")
+      , (9, "yhdeksännestä")
+      , (10, "kymmenennestä")
+      , (11, "yhdennestätoista")
+      , (12, "kahdennestatoista")
+      , (13, "kolmannestatoista")
+      , (14, "neljännestätoista")
+      , (15, "viidennestätoista")
+      , (16, "kuudennestatoista")
+      , (17, "seitsemännestätoista")
+      , (18, "kahdeksannestatoista")
+      , (19, "yhdeksännestätoista")
+      , (20, "kahdennestakymmenennestä")
+      , (21, "kahdennestakymmenennestäensimmäisestä")
+      , (100, "sadannesta")
+      , (1000, "tuhannennesta")
+      ]
+    )
+  , ( "singular locative illative"
+    , singular $ locativeIllative defaultInflection
+    , [ (0, "nollanteen")
+      , (1, "ensimmäiseen")
+      , (2, "toiseen")
+      , (3, "kolmanteen")
+      , (4, "neljänteen")
+      , (5, "viidenteen")
+      , (6, "kuudenteen")
+      , (7, "seitsemänteen")
+      , (8, "kahdeksanteen")
+      , (9, "yhdeksänteen")
+      , (10, "kymmenenteen")
+      , (11, "yhdenteentoista")
+      , (12, "kahdenteentoista")
+      , (13, "kolmanteentoista")
+      , (14, "neljänteentoista")
+      , (15, "viidenteentoista")
+      , (16, "kuudenteentoista")
+      , (17, "seitsemänteentoista")
+      , (18, "kahdeksanteentoista")
+      , (19, "yhdeksänteentoista")
+      , (20, "kahdenteenkymmenenteen")
+      , (21, "kahdenteenkymmenenteenensimmäiseen")
+      , (100, "sadanteen")
+      , (1000, "tuhannenteen")
+      ]
+    )
+  , ( "singular locative adessive"
+    , singular $ locativeAdessive defaultInflection
+    , [ (0, "nollannella")
+      , (1, "ensimmäisellä")
+      , (2, "toisella")
+      , (3, "kolmannella")
+      , (4, "neljännellä")
+      , (5, "viidennellä")
+      , (6, "kuudennella")
+      , (7, "seitsemännellä")
+      , (8, "kahdeksannella")
+      , (9, "yhdeksännellä")
+      , (10, "kymmenennellä")
+      , (11, "yhdennellätoista")
+      , (12, "kahdennellatoista")
+      , (13, "kolmannellatoista")
+      , (14, "neljännellätoista")
+      , (15, "viidennellätoista")
+      , (16, "kuudennellatoista")
+      , (17, "seitsemännellätoista")
+      , (18, "kahdeksannellatoista")
+      , (19, "yhdeksännellätoista")
+      , (20, "kahdennellakymmenennellä")
+      , (21, "kahdennellakymmenennelläensimmäisellä")
+      , (100, "sadannella")
+      , (1000, "tuhannennella")
+      ]
+    )
+  , ( "singular locative ablative"
+    , singular $ locativeAblative defaultInflection
+    , [ (0, "nollannelta")
+      , (1, "ensimmäiseltä")
+      , (2, "toiselta")
+      , (3, "kolmannelta")
+      , (4, "neljänneltä")
+      , (5, "viidenneltä")
+      , (6, "kuudennelta")
+      , (7, "seitsemänneltä")
+      , (8, "kahdeksannelta")
+      , (9, "yhdeksänneltä")
+      , (10, "kymmenenneltä")
+      , (11, "yhdenneltätoista")
+      , (12, "kahdenneltatoista")
+      , (13, "kolmanneltatoista")
+      , (14, "neljänneltätoista")
+      , (15, "viidenneltätoista")
+      , (16, "kuudenneltatoista")
+      , (17, "seitsemänneltätoista")
+      , (18, "kahdeksanneltatoista")
+      , (19, "yhdeksänneltätoista")
+      , (20, "kahdenneltakymmenenneltä")
+      , (21, "kahdenneltakymmenenneltäensimmäiseltä")
+      , (100, "sadannelta")
+      , (1000, "tuhannennelta")
+      ]
+    )
+  , ( "singular locative allative"
+    , singular $ locativeAllative defaultInflection
+    , [ (0, "nollannelle")
+      , (1, "ensimmäiselle")
+      , (2, "toiselle")
+      , (3, "kolmannelle")
+      , (4, "neljännelle")
+      , (5, "viidennelle")
+      , (6, "kuudennelle")
+      , (7, "seitsemännelle")
+      , (8, "kahdeksannelle")
+      , (9, "yhdeksännelle")
+      , (10, "kymmenennelle")
+      , (11, "yhdennelletoista")
+      , (12, "kahdennelletoista")
+      , (13, "kolmannelletoista")
+      , (14, "neljännelletoista")
+      , (15, "viidennelletoista")
+      , (16, "kuudennelletoista")
+      , (17, "seitsemännelletoista")
+      , (18, "kahdeksannelletoista")
+      , (19, "yhdeksännelletoista")
+      , (20, "kahdennellekymmenennelle")
+      , (21, "kahdennellekymmenennelleensimmäiselle")
+      , (100, "sadannelle")
+      , (1000, "tuhannennelle")
+      ]
+    )
+  , ( "singular abessive"
+    , singular $ abessive defaultInflection
+    , [ (0, "nollannetta")
+      , (1, "ensimmäisettä")
+      , (2, "toisetta")
+      , (3, "kolmannetta")
+      , (4, "neljännettä")
+      , (5, "viidennettä")
+      , (6, "kuudennetta")
+      , (7, "seitsemännettä")
+      , (8, "kahdeksannetta")
+      , (9, "yhdeksännettä")
+      , (10, "kymmenennettä")
+      , (11, "yhdennettätoista")
+      , (12, "kahdennettatoista")
+      , (13, "kolmannettatoista")
+      , (14, "neljännettätoista")
+      , (15, "viidennettätoista")
+      , (16, "kuudennettatoista")
+      , (17, "seitsemännettätoista")
+      , (18, "kahdeksannettatoista")
+      , (19, "yhdeksännettätoista")
+      , (20, "kahdennettakymmenennettä")
+      , (21, "kahdennettakymmenennettäensimmäisettä")
+      , (100, "sadannetta")
+      , (1000, "tuhannennetta")
+      ]
+    )
+  , ( "singular comitative"
+    , singular $ comitative defaultInflection
+    , [ (4, "neljänsine") ]
+    )
+  , ( "singular instructive"
+    , singular $ instructive defaultInflection
+    , [ (4, "neljänsin") ]
+    )
+  , ( "plural nominative"
+    , plural $ nominative defaultInflection
+    , [ (0, "nollannet")
+      , (1, "ensimmäiset")
+      , (2, "toiset")
+      , (3, "kolmannet")
+      , (4, "neljännet")
+      , (5, "viidennet")
+      , (6, "kuudennet")
+      , (7, "seitsemännet")
+      , (8, "kahdeksannet")
+      , (9, "yhdeksännet")
+      , (10, "kymmenennet")
+      , (11, "yhdennettoista")
+      , (12, "kahdennettoista")
+      , (13, "kolmannettoista")
+      , (14, "neljännettoista")
+      , (15, "viidennettoista")
+      , (16, "kuudennettoista")
+      , (17, "seitsemännettoista")
+      , (18, "kahdeksannettoista")
+      , (19, "yhdeksännettoista")
+      , (20, "kahdennetkymmenennet")
+      , (21, "kahdennetkymmenennetensimmäiset")
+      , (100, "sadannet")
+      , (1000, "tuhannennet")
+      ]
+    )
+  , ( "plural accusative"
+    , plural $ accusative defaultInflection
+    , [ (0, "nollannet")
+      , (1, "ensimmäiset")
+      , (2, "toiset")
+      , (3, "kolmannet")
+      , (4, "neljännet")
+      , (5, "viidennet")
+      , (6, "kuudennet")
+      , (7, "seitsemännet")
+      , (8, "kahdeksannet")
+      , (9, "yhdeksännet")
+      , (10, "kymmenennet")
+      , (11, "yhdennettoista")
+      , (12, "kahdennettoista")
+      , (13, "kolmannettoista")
+      , (14, "neljännettoista")
+      , (15, "viidennettoista")
+      , (16, "kuudennettoista")
+      , (17, "seitsemännettoista")
+      , (18, "kahdeksannettoista")
+      , (19, "yhdeksännettoista")
+      , (20, "kahdennetkymmenennet")
+      , (21, "kahdennetkymmenennetensimmäiset")
+      , (100, "sadannet")
+      , (1000, "tuhannennet")
+      ]
+    )
+  , ( "plural genitive"
+    , plural $ genitive defaultInflection
+    , [ (0, "nollansien")
+      , (1, "ensimmäisten")
+      , (2, "toisten")
+      , (3, "kolmansien")
+      , (4, "neljänsien")
+      , (5, "viidensien")
+      , (6, "kuudensien")
+      , (7, "seitsemänsien")
+      , (8, "kahdeksansien")
+      , (9, "yhdeksänsien")
+      , (10, "kymmenensien")
+      , (11, "yhdensientoista")
+      , (12, "kahdensientoista")
+      , (13, "kolmansientoista")
+      , (14, "neljänsientoista")
+      , (15, "viidensientoista")
+      , (16, "kuudensientoista")
+      , (17, "seitsemänsientoista")
+      , (18, "kahdeksansientoista")
+      , (19, "yhdeksänsientoista")
+      , (20, "kahdensienkymmenensien")
+      , (21, "kahdensienkymmenensienensimmäisten")
+      , (100, "sadansien")
+      , (1000, "tuhannensien")
+      ]
+    )
+  , ( "plural partitive"
+    , plural $ partitive defaultInflection
+    , [ (0, "nollansia")
+      , (1, "ensimmäisiä")
+      , (2, "toisia")
+      , (3, "kolmansia")
+      , (4, "neljänsiä")
+      , (5, "viidensiä")
+      , (6, "kuudensia")
+      , (7, "seitsemänsiä")
+      , (8, "kahdeksansia")
+      , (9, "yhdeksänsiä")
+      , (10, "kymmenensiä")
+      , (11, "yhdensiätoista")
+      , (12, "kahdensiatoista")
+      , (13, "kolmansiatoista")
+      , (14, "neljänsiätoista")
+      , (15, "viidensiätoista")
+      , (16, "kuudensiatoista")
+      , (17, "seitsemänsiätoista")
+      , (18, "kahdeksansiatoista")
+      , (19, "yhdeksänsiätoista")
+      , (20, "kahdensiakymmenensiä")
+      , (21, "kahdensiakymmenensiäensimmäisiä")
+      , (100, "sadansia")
+      , (1000, "tuhannensia")
+      ]
+    )
+  , ( "plural essive"
+    , plural $ essive defaultInflection
+    , [ (0, "nollansina")
+      , (1, "ensimmäisinä")
+      , (2, "toisina")
+      , (3, "kolmansina")
+      , (4, "neljänsinä")
+      , (5, "viidensinä")
+      , (6, "kuudensina")
+      , (7, "seitsemänsinä")
+      , (8, "kahdeksansina")
+      , (9, "yhdeksänsinä")
+      , (10, "kymmenensinä")
+      , (11, "yhdensinätoista")
+      , (12, "kahdensinatoista")
+      , (13, "kolmansinatoista")
+      , (14, "neljänsinätoista")
+      , (15, "viidensinätoista")
+      , (16, "kuudensinatoista")
+      , (17, "seitsemänsinätoista")
+      , (18, "kahdeksansinatoista")
+      , (19, "yhdeksänsinätoista")
+      , (20, "kahdensinakymmenensinä")
+      , (21, "kahdensinakymmenensinäensimmäisinä")
+      , (100, "sadansina")
+      , (1000, "tuhannensina")
+      ]
+    )
+  , ( "plural translative"
+    , plural $ translative defaultInflection
+    , [ (0, "nollansiksi")
+      , (1, "ensimmäisiksi")
+      , (2, "toisiksi")
+      , (3, "kolmansiksi")
+      , (4, "neljänsiksi")
+      , (5, "viidensiksi")
+      , (6, "kuudensiksi")
+      , (7, "seitsemänsiksi")
+      , (8, "kahdeksansiksi")
+      , (9, "yhdeksänsiksi")
+      , (10, "kymmenensiksi")
+      , (11, "yhdensiksitoista")
+      , (12, "kahdensiksitoista")
+      , (13, "kolmansiksitoista")
+      , (14, "neljänsiksitoista")
+      , (15, "viidensiksitoista")
+      , (16, "kuudensiksitoista")
+      , (17, "seitsemänsiksitoista")
+      , (18, "kahdeksansiksitoista")
+      , (19, "yhdeksänsissätoista")
+      , (20, "kahdensiksikymmenensiksi")
+      , (21, "kahdensiksikymmenensiksiensimmäisiksi")
+      , (100, "sadansiksi")
+      , (1000, "tuhannensiksi")
+      ]
+    )
+  , ( "plural locative inessive"
+    , plural $ locativeInessive defaultInflection
+    , [ (0, "nollansissa")
+      , (1, "ensimmäisissä")
+      , (2, "toisissa")
+      , (3, "kolmansissa")
+      , (4, "neljänsissä")
+      , (5, "viidensissä")
+      , (6, "kuudensissa")
+      , (7, "seitsemänsissä")
+      , (8, "kahdeksansissa")
+      , (9, "yhdeksänsissä")
+      , (10, "kymmenensissä")
+      , (11, "yhdensissätoista")
+      , (12, "kahdensissatoista")
+      , (13, "kolmansissatoista")
+      , (14, "neljänsissätoista")
+      , (15, "viidensissätoista")
+      , (16, "kuudensissatoista")
+      , (17, "seitsemänsissätoista")
+      , (18, "kahdeksansissatoista")
+      , (19, "yhdeksänsissätoista")
+      , (20, "kahdensissakymmenensissä")
+      , (21, "kahdensissakymmenensissäensimmäisissä")
+      , (100, "sadansissa")
+      , (1000, "tuhannensissa")
+      ]
+    )
+  , ( "plural locative elative"
+    , plural $ locativeElative defaultInflection
+    , [ (0, "nollansista")
+      , (1, "ensimmäisistä")
+      , (2, "toisista")
+      , (3, "kolmansista")
+      , (4, "neljänsistä")
+      , (5, "viidensistä")
+      , (6, "kuudensista")
+      , (7, "seitsemänsistä")
+      , (8, "kahdeksansista")
+      , (9, "yhdeksänsistä")
+      , (10, "kymmenensistä")
+      , (11, "yhdensistätoista")
+      , (12, "kahdensistatoista")
+      , (13, "kolmansistatoista")
+      , (14, "neljänsistätoista")
+      , (15, "viidensistätoista")
+      , (16, "kuudensistatoista")
+      , (17, "seitsemänsistätoista")
+      , (18, "kahdeksansistatoista")
+      , (19, "yhdeksänsistätoista")
+      , (20, "kahdensistakymmenensistä")
+      , (21, "kahdensistakymmenensistäensimmäisistä")
+      , (100, "sadansista")
+      , (1000, "tuhannensista")
+      ]
+    )
+  , ( "plural locative illative"
+    , plural $ locativeIllative defaultInflection
+    , [ (0, "nollansiin")
+      , (1, "ensimmäisiin")
+      , (2, "toisiin")
+      , (3, "kolmansiin")
+      , (4, "neljänsiin")
+      , (5, "viidensiin")
+      , (6, "kuudensiin")
+      , (7, "seitsemänsiin")
+      , (8, "kahdeksansiin")
+      , (9, "yhdeksänsiin")
+      , (10, "kymmenensiin")
+      , (11, "yhdensiintoista")
+      , (12, "kahdensiintoista")
+      , (13, "kolmansiintoista")
+      , (14, "neljänsiintoista")
+      , (15, "viidensiintoista")
+      , (16, "kuudensiintoista")
+      , (17, "seitsemänsiintoista")
+      , (18, "kahdeksansiintoista")
+      , (19, "yhdeksänsiintoista")
+      , (20, "kahdensiinkymmenensiin")
+      , (21, "kahdensiinkymmenensiinensimmäisiin")
+      , (100, "sadansiin")
+      , (1000, "tuhannensiin")
+      ]
+    )
+  , ( "plural locative adessive"
+    , plural $ locativeAdessive defaultInflection
+    , [ (0, "nollansilla")
+      , (1, "ensimmäisillä")
+      , (2, "toisilla")
+      , (3, "kolmansilla")
+      , (4, "neljänsillä")
+      , (5, "viidensillä")
+      , (6, "kuudensilla")
+      , (7, "seitsemänsillä")
+      , (8, "kahdeksansilla")
+      , (9, "yhdeksänsillä")
+      , (10, "kymmenensillä")
+      , (11, "yhdensillätoista")
+      , (12, "kahdensillatoista")
+      , (13, "kolmansillatoista")
+      , (14, "neljänsillätoista")
+      , (15, "viidensillätoista")
+      , (16, "kuudensillatoista")
+      , (17, "seitsemänsillätoista")
+      , (18, "kahdeksansillatoista")
+      , (19, "yhdeksänsillätoista")
+      , (20, "kahdensillakymmenensillä")
+      , (21, "kahdensillakymmenensilläensimmäisillä")
+      , (100, "sadansilla")
+      , (1000, "tuhannensilla")
+      ]
+    )
+  , ( "plural locative ablative"
+    , plural $ locativeAblative defaultInflection
+    , [ (0, "nollansilta")
+      , (1, "ensimmäisiltä")
+      , (2, "toisilta")
+      , (3, "kolmansilta")
+      , (4, "neljänsiltä")
+      , (5, "viidensiltä")
+      , (6, "kuudensilta")
+      , (7, "seitsemänsiltä")
+      , (8, "kahdeksansilta")
+      , (9, "yhdeksänsiltä")
+      , (10, "kymmenensiltä")
+      , (11, "yhdensitlätoista")
+      , (12, "kahdensiltatoista")
+      , (13, "kolmansiltatoista")
+      , (14, "neljänsiltätoista")
+      , (15, "viidensiltätoista")
+      , (16, "kuudensiltatoista")
+      , (17, "seitsemänsiltätoista")
+      , (18, "kahdeksansiltatoista")
+      , (19, "yhdeksänsiltätoista")
+      , (20, "kahdensiltakymmenensiltä")
+      , (21, "kahdensiltakymmenensiltäensimmäisiltä")
+      , (100, "sadansilta")
+      , (1000, "tuhannensilta")
+      ]
+    )
+  , ( "plural locative allative"
+    , plural $ locativeAllative defaultInflection
+    , [ (0, "nollansille")
+      , (1, "ensimmäisille")
+      , (2, "toisille")
+      , (3, "kolmansille")
+      , (4, "neljänsille")
+      , (5, "viidensille")
+      , (6, "kuudensille")
+      , (7, "seitsemänsille")
+      , (8, "kahdeksansille")
+      , (9, "yhdeksänsille")
+      , (10, "kymmenensille")
+      , (11, "yhdensiintoista")
+      , (12, "kahdensilletoista")
+      , (13, "kolmansilletoista")
+      , (14, "neljänsilletoista")
+      , (15, "viidensilletoista")
+      , (16, "kuudensilletoista")
+      , (17, "seitsemänsilletoista")
+      , (18, "kahdeksansilletoista")
+      , (19, "yhdeksänsilletoista")
+      , (20, "kahdensillekymmenensille")
+      , (21, "kahdensillekymmenensilleensimmäisille")
+      , (100, "sadansille")
+      , (1000, "tuhannensille")
+      ]
+    )
+  , ( "plural abessive"
+    , plural $ abessive defaultInflection
+    , [ (0, "nollansitta")
+      , (1, "ensimmäisittä")
+      , (2, "toisitta")
+      , (3, "kolmansitta")
+      , (4, "neljänsittä")
+      , (5, "viidensittä")
+      , (6, "kuudensitta")
+      , (7, "seitsemänsittä")
+      , (8, "kahdeksansitta")
+      , (9, "yhdeksänsittä")
+      , (10, "kymmenensittä")
+      , (11, "yhdensittätoista")
+      , (12, "kahdensittatoista")
+      , (13, "kolmansittatoista")
+      , (14, "neljänsittätoista")
+      , (15, "viidensittätoista")
+      , (16, "kuudensittatoista")
+      , (17, "seitsemänsittätoista")
+      , (18, "kahdeksansittatoista")
+      , (19, "yhdeksänsittätoista")
+      , (20, "kahdensittakymmenensittä")
+      , (21, "kahdensittakymmenensittäensimmäisittä")
+      , (100, "sadansitta")
+      , (1000, "tuhannensitta")
+      ]
+    )
+  , ( "plural comitative"
+    , plural $ comitative defaultInflection
+    , [ (0, "nollansine")
+      , (1, "ensimmäisine")
+      , (2, "toisine")
+      , (3, "kolmansine")
+      , (4, "neljänsine")
+      , (5, "viidensine")
+      , (6, "kuudensine")
+      , (7, "seitsemänsine")
+      , (8, "kahdeksansine")
+      , (9, "yhdeksänsine")
+      , (10, "kymmenensine")
+      , (11, "yhdensinetoista")
+      , (12, "kahdensinetoista")
+      , (13, "kolmansinetoista")
+      , (14, "neljänsinetoista")
+      , (15, "viidensinetoista")
+      , (16, "kuudensinetoista")
+      , (17, "seitsemänsinetoista")
+      , (18, "kahdeksansinetoista")
+      , (19, "yhdeksänsinetoista")
+      , (20, "kahdensinekymmenensine")
+      , (21, "kahdensinekymmenensineensimmäisine")
+      , (100, "sadansine")
+      , (1000, "tuhannensine")
+      ]
+    )
+  , ( "plural instructive"
+    , plural $ instructive defaultInflection
+    , [ (0, "nollansin")
+      , (1, "ensimmäisin")
+      , (2, "toisin")
+      , (3, "kolmansin")
+      , (4, "neljänsin")
+      , (5, "viidensin")
+      , (6, "kuudensin")
+      , (7, "seitsemänsin")
+      , (8, "kahdeksansin")
+      , (9, "yhdeksänsin")
+      , (10, "kymmenensin")
+      , (11, "yhdensintoista")
+      , (12, "kahdensintoista")
+      , (13, "kolmansintoista")
+      , (14, "neljänsintoista")
+      , (15, "viidensintoista")
+      , (16, "kuudensintoista")
+      , (17, "seitsemänsintoista")
+      , (18, "kahdeksansintoista")
+      , (19, "yhdeksänsintoista")
+      , (20, "kahdensinkymmenensin")
+      , (21, "kahdensinkymmenensinensimmäisin")
+      , (100, "sadansin")
+      , (1000, "tuhannensin")
+      ]
+    )
+  ]
+
+multiplicatives ∷ (Integral i) ⇒ TestData i
+multiplicatives =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "kerran")
+      , (2, "kahdesti")
+      , (6, "kuudesti")
+      ]
+    )
+  ]
+
+multipliers ∷ (Integral i) ⇒ TestData i
+multipliers =
+  [ ( "default"
+    , defaultInflection
+    , [ (6, "kuusinkertainen")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/FO/TestData.hs b/src-test/Text/Numeral/Language/FO/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/FO/TestData.hs
@@ -0,0 +1,225 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        fo
+
+[@ISO639-2@]        fao
+
+[@ISO639-3@]        fao
+
+[@Native name@]     føroyskt
+
+[@English name@]    Faroese
+-}
+module Text.Numeral.Language.FO.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-faroese/en/fao/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "null")
+      , (1, "ein")
+      , (2, "tveir")
+      , (3, "tríggir")
+      , (4, "fýra")
+      , (5, "fimm")
+      , (6, "seks")
+      , (7, "sjey")
+      , (8, "átta")
+      , (9, "níggju")
+      , (10, "tíggju")
+      , (11, "ellivu")
+      , (12, "tólv")
+      , (13, "trettan")
+      , (14, "fjúrtan")
+      , (15, "fimtan")
+      , (16, "sekstan")
+      , (17, "seytjan")
+      , (18, "átjan")
+      , (19, "nítjan")
+      , (20, "tjúgu")
+      , (21, "ein og tjúgu")
+      , (22, "tveir og tjúgu")
+      , (23, "tríggir og tjúgu")
+      , (24, "fýra og tjúgu")
+      , (25, "fimm og tjúgu")
+      , (26, "seks og tjúgu")
+      , (27, "sjey og tjúgu")
+      , (28, "átta og tjúgu")
+      , (29, "níggju og tjúgu")
+      , (30, "tríati")
+      , (31, "ein og tríati")
+      , (32, "tveir og tríati")
+      , (33, "tríggir og tríati")
+      , (34, "fýra og tríati")
+      , (35, "fimm og tríati")
+      , (36, "seks og tríati")
+      , (37, "sjey og tríati")
+      , (38, "átta og tríati")
+      , (39, "níggju og tríati")
+      , (40, "fýrati")
+      , (41, "ein og fýrati")
+      , (42, "tveir og fýrati")
+      , (43, "tríggir og fýrati")
+      , (44, "fýra og fýrati")
+      , (45, "fimm og fýrati")
+      , (46, "seks og fýrati")
+      , (47, "sjey og fýrati")
+      , (48, "átta og fýrati")
+      , (49, "níggju og fýrati")
+      , (50, "fimmti")
+      , (51, "ein og fimmti")
+      , (52, "tveir og fimmti")
+      , (53, "tríggir og fimmti")
+      , (54, "fýra og fimmti")
+      , (55, "fimm og fimmti")
+      , (56, "seks og fimmti")
+      , (57, "sjey og fimmti")
+      , (58, "átta og fimmti")
+      , (59, "níggju og fimmti")
+      , (60, "seksti")
+      , (61, "ein og seksti")
+      , (62, "tveir og seksti")
+      , (63, "tríggir og seksti")
+      , (64, "fýra og seksti")
+      , (65, "fimm og seksti")
+      , (66, "seks og seksti")
+      , (67, "sjey og seksti")
+      , (68, "átta og seksti")
+      , (69, "níggju og seksti")
+      , (70, "sjeyti")
+      , (71, "ein og sjeyti")
+      , (72, "tveir og sjeyti")
+      , (73, "tríggir og sjeyti")
+      , (74, "fýra og sjeyti")
+      , (75, "fimm og sjeyti")
+      , (76, "seks og sjeyti")
+      , (77, "sjey og sjeyti")
+      , (78, "átta og sjeyti")
+      , (79, "níggju og sjeyti")
+      , (80, "áttati")
+      , (81, "ein og áttati")
+      , (82, "tveir og áttati")
+      , (83, "tríggir og áttati")
+      , (84, "fýra og áttati")
+      , (85, "fimm og áttati")
+      , (86, "seks og áttati")
+      , (87, "sjey og áttati")
+      , (88, "átta og áttati")
+      , (89, "níggju og áttati")
+      , (90, "níti")
+      , (91, "ein og níti")
+      , (92, "tveir og níti")
+      , (93, "tríggir og níti")
+      , (94, "fýra og níti")
+      , (95, "fimm og níti")
+      , (96, "seks og níti")
+      , (97, "sjey og níti")
+      , (98, "átta og níti")
+      , (99, "níggju og níti")
+      , (100, "hundrað")
+      , (101, "hundrað og ein")
+      , (102, "hundrað og tveir")
+      , (103, "hundrað og tríggir")
+      , (104, "hundrað og fýra")
+      , (105, "hundrað og fimm")
+      , (106, "hundrað og seks")
+      , (107, "hundrað og sjey")
+      , (108, "hundrað og átta")
+      , (109, "hundrað og níggju")
+      , (110, "hundrað og tíggju")
+      , (123, "hundrað og tríggir og tjúgu")
+      , (200, "tvey hundrað")
+      , (300, "trý hundrað")
+      , (321, "trý hundrað og ein og tjúgu")
+      , (400, "fýra hundrað")
+      , (500, "fimm hundrað")
+      , (600, "seks hundrað")
+      , (700, "sjey hundrað")
+      , (800, "átta hundrað")
+      , (900, "níggju hundrað")
+      , (909, "níggju hundrað og níggju")
+      , (990, "níggju hundrað og níti")
+      , (999, "níggju hundrað og níggju og níti")
+      , (1000, "túsund")
+      , (1001, "eitt túsund og ein")
+      , (1008, "eitt túsund og átta")
+      , (1234, "eitt túsund tvey hundrað og fýra og tríati")
+      , (2000, "tvey túsund")
+      , (3000, "trý túsund")
+      , (4000, "fýra túsund")
+      , (4321, "fýra túsund trý hundrað og ein og tjúgu")
+      , (5000, "fimm túsund")
+      , (6000, "seks túsund")
+      , (7000, "sjey túsund")
+      , (8000, "átta túsund")
+      , (9000, "níggju túsund")
+      , (10000, "tíggju túsund")
+      , (12345, "tólv túsund trý hundrað og fimm og fýrati")
+      , (20000, "tjúgu túsund")
+      , (30000, "tríati túsund")
+      , (40000, "fýrati túsund")
+      , (50000, "fimmti túsund")
+      , (54321, "fýra og fimmti túsund trý hundrað og ein og tjúgu")
+      , (60000, "seksti túsund")
+      , (70000, "sjeyti túsund")
+      , (80000, "áttati túsund")
+      , (90000, "níti túsund")
+      , (100000, "hundrað túsund")
+      , (123456, "hundrað og tríggir og tjúgu túsund og fýra hundrað og seks og fimmti")
+      , (200000, "tvey hundrað túsund")
+      , (300000, "trý hundrað túsund")
+      , (400000, "fýra hundrað túsund")
+      , (500000, "fimm hundrað túsund")
+      , (600000, "seks hundrað túsund")
+      , (654321, "seks hundrað og fýra og fimmti túsund trý hundrað og ein og tjúgu")
+      , (700000, "sjey hundrað túsund")
+      , (800000, "átta hundrað túsund")
+      , (900000, "níggju hundrað túsund")
+      , (1000000, "ein millión")
+      , (1000001, "ein millión og ein")
+      , (1234567, "ein millión tvey hundrað og fýra og tríati túsund og fimm hundrað og sjey og seksti")
+      , (2000000, "tvær milliónir")
+      , (3000000, "tríggjar milliónir")
+      , (4000000, "fýra milliónir")
+      , (5000000, "fimm milliónir")
+      , (6000000, "seks milliónir")
+      , (7000000, "sjey milliónir")
+      , (7654321, "sjey milliónir og seks hundrað og fýra og fimmti túsund trý hundrað og ein og tjúgu")
+      , (8000000, "átta milliónir")
+      , (9000000, "níggju milliónir")
+      , (1000000000, "ein milliard")
+      , (1000000001, "ein milliard og ein")
+      , (2000000000, "tveir milliardir")
+      , (3000000000, "tríggir milliardir")
+      , (4000000000, "fýra milliardir")
+      , (5000000000, "fimm milliardir")
+      , (6000000000, "seks milliardir")
+      , (7000000000, "sjey milliardir")
+      , (8000000000, "átta milliardir")
+      , (9000000000, "níggju milliardir")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/FR/TestData.hs b/src-test/Text/Numeral/Language/FR/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/FR/TestData.hs
@@ -0,0 +1,371 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        fr
+
+[@ISO639-2B@]       fre
+
+[@ISO639-3@]        fra
+
+[@Native name@]     Français
+
+[@English name@]    French
+-}
+
+module Text.Numeral.Language.FR.TestData (cardinals, ordinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "numerals" Text.Numeral.Grammar
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.sf.airnet.ne.jp/~ts/language/number/french.html
+  http://www.french-linguistics.co.uk/tutorials/numbers/
+  http://www.parisbypod.com/2007/10/23/french-ordinal-numbers/
+-}
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "masculine"
+    , masculine defaultInflection
+    , [ (0, "zéro")
+      , (1, "un")
+      , (2, "deux")
+      , (3, "trois")
+      , (4, "quatre")
+      , (5, "cinq")
+      , (6, "six")
+      , (7, "sept")
+      , (8, "huit")
+      , (9, "neuf")
+      , (10, "dix")
+      , (11, "onze")
+      , (12, "douze")
+      , (13, "treize")
+      , (14, "quatorze")
+      , (15, "quinze")
+      , (16, "seize")
+      , (17, "dix-sept")
+      , (18, "dix-huit")
+      , (19, "dix-neuf")
+      , (20, "vingt")
+      , (21, "vingt et un")
+      , (22, "vingt-deux")
+      , (23, "vingt-trois")
+      , (24, "vingt-quatre")
+      , (25, "vingt-cinq")
+      , (26, "vingt-six")
+      , (27, "vingt-sept")
+      , (28, "vingt-huit")
+      , (29, "vingt-neuf")
+      , (30, "trente")
+      , (31, "trente et un")
+      , (32, "trente-deux")
+      , (33, "trente-trois")
+      , (34, "trente-quatre")
+      , (35, "trente-cinq")
+      , (36, "trente-six")
+      , (37, "trente-sept")
+      , (38, "trente-huit")
+      , (39, "trente-neuf")
+      , (40, "quarante")
+      , (41, "quarante et un")
+      , (42, "quarante-deux")
+      , (43, "quarante-trois")
+      , (44, "quarante-quatre")
+      , (45, "quarante-cinq")
+      , (46, "quarante-six")
+      , (47, "quarante-sept")
+      , (48, "quarante-huit")
+      , (49, "quarante-neuf")
+      , (50, "cinquante")
+      , (51, "cinquante et un")
+      , (52, "cinquante-deux")
+      , (53, "cinquante-trois")
+      , (54, "cinquante-quatre")
+      , (55, "cinquante-cinq")
+      , (56, "cinquante-six")
+      , (57, "cinquante-sept")
+      , (58, "cinquante-huit")
+      , (59, "cinquante-neuf")
+      , (60, "soixante")
+      , (61, "soixante et un")
+      , (62, "soixante-deux")
+      , (63, "soixante-trois")
+      , (64, "soixante-quatre")
+      , (65, "soixante-cinq")
+      , (66, "soixante-six")
+      , (67, "soixante-sept")
+      , (68, "soixante-huit")
+      , (69, "soixante-neuf")
+      , (70, "soixante-dix")
+      , (71, "soixante et onze")
+      , (72, "soixante-douze")
+      , (73, "soixante-treize")
+      , (74, "soixante-quatorze")
+      , (75, "soixante-quinze")
+      , (76, "soixante-seize")
+      , (77, "soixante-dix-sept")
+      , (78, "soixante-dix-huit")
+      , (79, "soixante-dix-neuf")
+      , (80, "quatre-vingts")
+      , (81, "quatre-vingt-un")
+      , (82, "quatre-vingt-deux")
+      , (83, "quatre-vingt-trois")
+      , (84, "quatre-vingt-quatre")
+      , (85, "quatre-vingt-cinq")
+      , (86, "quatre-vingt-six")
+      , (87, "quatre-vingt-sept")
+      , (88, "quatre-vingt-huit")
+      , (89, "quatre-vingt-neuf")
+      , (90, "quatre-vingt-dix")
+      , (91, "quatre-vingt-onze")
+      , (92, "quatre-vingt-douze")
+      , (93, "quatre-vingt-treize")
+      , (94, "quatre-vingt-quatorze")
+      , (95, "quatre-vingt-quinze")
+      , (96, "quatre-vingt-seize")
+      , (97, "quatre-vingt-dix-sept")
+      , (98, "quatre-vingt-dix-huit")
+      , (99, "quatre-vingt-dix-neuf")
+      , (100, "cent")
+      , (101, "cent et un")
+      , (102, "cent deux")
+      , (103, "cent trois")
+      , (104, "cent quatre")
+      , (105, "cent cinq")
+      , (111, "cent et onze")
+      , (122, "cent vingt-deux")
+      , (123, "cent vingt-trois")
+      , (144, "cent quarante-quatre")
+      , (196, "cent quatre-vingt-seize")
+      , (199, "cent quatre-vingt-dix-neuf")
+      , (200, "deux cents")
+      , (300, "trois cents")
+      , (400, "quatre cents")
+      , (500, "cinq cents")
+      , (600, "six cents")
+      , (700, "sept cents")
+      , (800, "huit cents")
+      , (900, "neuf cents")
+      , (1000, "mille")
+      , (1999, "mille neuf cent quatre-vingt-dix-neuf")
+      , (2000, "deux mille")
+      , (2999, "deux mille neuf cent quatre-vingt-dix-neuf")
+      , (dec 4, "dix mille")
+      , (dec 5, "cent mille")
+      , (dec 6, "un million")
+      , (dec 9, "un milliard")
+      , (dec 12, "un billion")
+      , (dec 15, "un billiard")
+      , (dec 18, "un trillion")
+      , (dec 21, "un trilliard")
+      , (dec 24, "un quadrillion")
+      , (dec 27, "un quadrilliard")
+      , (dec 30, "un quintillion")
+      , (dec 33, "un quintilliard")
+      , (dec 36, "un sextillion")
+      , (dec 39, "un sextilliard")
+      , (dec 42, "un septillion")
+      , (dec 45, "un septilliard")
+      , (dec 48, "un octillion")
+      , (dec 51, "un octilliard")
+      , (dec 54, "un nonillion")
+      , (dec 57, "un nonilliard")
+      , (dec 60, "un décillion")
+      , (dec 63, "un décilliard")
+      , (dec 66, "un unodécillion")
+      , (dec 69, "un unodécilliard")
+      , (dec 72, "un duodécillion")
+      , (dec 75, "un duodécilliard")
+      , (dec 78, "un trédécillion")
+      , (dec 81, "un trédécilliard")
+      , (dec 84, "un quattuordécillion")
+      , (dec 87, "un quattuordécilliard")
+      , (dec 90, "un quindécillion")
+      , (dec 93, "un quindécilliard")
+      , (dec 96, "un sexdécillion")
+      , (dec 99, "un sexdécilliard")
+      , (dec 102, "un septendécillion")
+      , (dec 105, "un septendécilliard")
+      , (dec 108, "un octodécillion")
+      , (dec 111, "un octodécilliard")
+      , (dec 114, "un novemdécillion")
+      , (dec 117, "un novemdécilliard")
+      , (dec 120, "un vigintillion")
+      , (dec 123, "un vigintilliard")
+      , (dec 150, "un quinquavigintillion")
+      , (dec 153, "un quinquavigintilliard")
+      , (dec 180, "un trigintillion")
+      , (dec 183, "un trigintilliard")
+      , (dec 210, "un quinquatrigintillion")
+      , (dec 213, "un quinquatrigintilliard")
+      , (dec 240, "un quadragintillion")
+      , (dec 243, "un quadragintilliard")
+      , (dec 270, "un quinquaquadragintillion")
+      , (dec 273, "un quinquaquadragintilliard")
+      , (dec 300, "un quinquagintillion")
+      , (dec 303, "un quinquagintilliard")
+      , (dec 306, "un unoquinquagintillion")
+      , (dec 309, "un unoquinquagintilliard")
+      , (dec 360, "un sexagintillion")
+      , (dec 363, "un sexagintilliard")
+      , (dec 420, "un septuagintillion")
+      , (dec 423, "un septuagintilliard")
+      , (dec 480, "un octogintillion")
+      , (dec 483, "un octogintilliard")
+      , (dec 540, "un nonagintillion")
+      , (dec 543, "un nonagintilliard")
+      , (dec 600, "un centillion")
+      , (dec 603, "un centilliard")
+      ]
+    )
+  , ( "feminine"
+    , feminine defaultInflection
+    , [ (1, "une")
+      ]
+    )
+  ]
+
+ordinals ∷ (Integral i) ⇒ TestData i
+ordinals =
+  [ ( "masculine"
+    , masculine defaultInflection
+    , [ (0, "zéroth")
+      , (1, "premier")
+      , (2, "deuxième")
+      , (3, "troisième")
+      , (4, "quatrième")
+      , (5, "cinquième")
+      , (6, "sixième")
+      , (7, "septième")
+      , (8, "huitième")
+      , (9, "neuvième")
+      , (10, "dixième")
+      , (11, "onzième")
+      , (12, "douzième")
+      , (13, "treizième")
+      , (14, "quatorzième")
+      , (15, "quinzième")
+      , (16, "seizième")
+      , (17, "dix-septième")
+      , (18, "dix-huitième")
+      , (19, "dix-neuvième")
+      , (20, "vingtième")
+      , (21, "vingt et unième")
+      , (22, "vingt-deuxième")
+      , (23, "vingt-troisième")
+      , (24, "vingt-quatrième")
+      , (25, "vingt-cinquième")
+      , (26, "vingt-sixième")
+      , (27, "vingt-septième")
+      , (28, "vingt-huitième")
+      , (29, "vingt-neuvième")
+      , (30, "trentième")
+      , (31, "trente et unième")
+      , (32, "trente-deuxième")
+      , (33, "trente-troisième")
+      , (34, "trente-quatrième")
+      , (35, "trente-cinquième")
+      , (36, "trente-sixième")
+      , (37, "trente-septième")
+      , (38, "trente-huitième")
+      , (39, "trente-neuvième")
+      , (40, "quarantième")
+      , (41, "quarante et unième")
+      , (42, "quarante-deuxième")
+      , (43, "quarante-troisième")
+      , (44, "quarante-quatrième")
+      , (45, "quarante-cinquième")
+      , (46, "quarante-sixième")
+      , (47, "quarante-septième")
+      , (48, "quarante-huitième")
+      , (49, "quarante-neuvième")
+      , (50, "cinquantième")
+      , (51, "cinquante et unième")
+      , (52, "cinquante-deuxième")
+      , (53, "cinquante-troisième")
+      , (54, "cinquante-quatrième")
+      , (55, "cinquante-cinquième")
+      , (56, "cinquante-sixième")
+      , (57, "cinquante-septième")
+      , (58, "cinquante-huitième")
+      , (59, "cinquante-neuvième")
+      , (60, "soixantième")
+      , (61, "soixante et unième")
+      , (62, "soixante-deuxième")
+      , (63, "soixante-troisième")
+      , (64, "soixante-quatrième")
+      , (65, "soixante-cinquième")
+      , (66, "soixante-sixième")
+      , (67, "soixante-septième")
+      , (68, "soixante-huitième")
+      , (69, "soixante-neuvième")
+      , (70, "soixante-dixième")
+      , (71, "soixante et onzième")
+      , (72, "soixante-douzième")
+      , (73, "soixante-treizième")
+      , (74, "soixante-quatorzième")
+      , (75, "soixante-quinzième")
+      , (76, "soixante-seizième")
+      , (77, "soixante-dix-septième")
+      , (78, "soixante-dix-huitième")
+      , (79, "soixante-dix-neuvième")
+      , (80, "quatre-vingtième")
+      , (81, "quatre-vingt-unième")
+      , (82, "quatre-vingt-deuxième")
+      , (83, "quatre-vingt-troisième")
+      , (84, "quatre-vingt-quatrième")
+      , (85, "quatre-vingt-cinquième")
+      , (86, "quatre-vingt-sixième")
+      , (87, "quatre-vingt-septième")
+      , (88, "quatre-vingt-huitième")
+      , (89, "quatre-vingt-neuvième")
+      , (90, "quatre-vingt-dixième")
+      , (91, "quatre-vingt-onzième")
+      , (92, "quatre-vingt-douzième")
+      , (93, "quatre-vingt-treizième")
+      , (94, "quatre-vingt-quatorzième")
+      , (95, "quatre-vingt-quinzième")
+      , (96, "quatre-vingt-seizième")
+      , (97, "quatre-vingt-dix-septième")
+      , (98, "quatre-vingt-dix-huitième")
+      , (99, "quatre-vingt-dix-neuvième")
+      , (100, "centième")
+      , (200, "deux centième")
+      , (300, "trois centième")
+      , (400, "quatre centième")
+      , (500, "cinq centième")
+      , (600, "six centième")
+      , (700, "sept centième")
+      , (800, "huit centième")
+      , (900, "neuf centième")
+      , (1000, "millième")
+      , (dec 6, "millionième")
+      , (dec 9, "milliardième")
+      ]
+    )
+  , ( "feminine"
+    , feminine defaultInflection
+    , [ (1, "première")
+      , (41, "quarante et uneième")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/FUR/TestData.hs b/src-test/Text/Numeral/Language/FUR/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/FUR/TestData.hs
@@ -0,0 +1,199 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        fur
+
+[@ISO639-3@]        fur
+
+[@Native name@]     Furlan
+
+[@English name@]    Friulan
+-}
+
+module Text.Numeral.Language.FUR.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Grammar
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+-- Sources:
+--   http://www.languagesandnumbers.com/how-to-count-in-friulian/en/fur/
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "masculine"
+    , masculine defaultInflection
+    , [ (0, "zero")
+      , (1, "un")
+      , (2, "doi")
+      , (3, "trê")
+      , (4, "cuatri")
+      , (5, "cinc")
+      , (6, "sîs")
+      , (7, "siet")
+      , (8, "vot")
+      , (9, "nûf")
+      , (10, "dîs")
+      , (11, "undis")
+      , (12, "dodis")
+      , (13, "tredis")
+      , (14, "cutuardis")
+      , (15, "cuindis")
+      , (16, "sedis")
+      , (17, "disesiet")
+      , (18, "disevot")
+      , (19, "disenûf")
+      , (20, "vincj")
+      , (21, "vincjeun")
+      , (22, "vincjedoi")
+      , (23, "vincjetrê")
+      , (24, "vincjecuatri")
+      , (25, "vincjecinc")
+      , (26, "vincjesîs")
+      , (27, "vincjesiet")
+      , (28, "vincjevot")
+      , (29, "vincjenûf")
+      , (30, "trente")
+      , (31, "trenteun")
+      , (32, "trentedoi")
+      , (33, "trentetrê")
+      , (34, "trentecuatri")
+      , (35, "trentecinc")
+      , (36, "trentesîs")
+      , (37, "trentesiet")
+      , (38, "trentevot")
+      , (39, "trentenûf")
+      , (40, "cuarante")
+      , (41, "cuaranteun")
+      , (42, "cuarantedoi")
+      , (43, "cuarantetrê")
+      , (44, "cuarantecuatri")
+      , (45, "cuarantecinc")
+      , (46, "cuarantesîs")
+      , (47, "cuarantesiet")
+      , (48, "cuarantevot")
+      , (49, "cuarantenûf")
+      , (50, "cincuante")
+      , (51, "cincuanteun")
+      , (52, "cincuantedoi")
+      , (53, "cincuantetrê")
+      , (54, "cincuantecuatri")
+      , (55, "cincuantecinc")
+      , (56, "cincuantesîs")
+      , (57, "cincuantesiet")
+      , (58, "cincuantevot")
+      , (59, "cincuantenûf")
+      , (60, "sessante")
+      , (61, "sessanteun")
+      , (62, "sessantedoi")
+      , (63, "sessantetrê")
+      , (64, "sessantecuatri")
+      , (65, "sessantecinc")
+      , (66, "sessantesîs")
+      , (67, "sessantesiet")
+      , (68, "sessantevot")
+      , (69, "sessantenûf")
+      , (70, "setante")
+      , (71, "setanteun")
+      , (72, "setantedoi")
+      , (73, "setantetrê")
+      , (74, "setantecuatri")
+      , (75, "setantecinc")
+      , (76, "setantesîs")
+      , (77, "setantesiet")
+      , (78, "setantevot")
+      , (79, "setantenûf")
+      , (80, "otante")
+      , (81, "otanteun")
+      , (82, "otantedoi")
+      , (83, "otantetrê")
+      , (84, "otantecuatri")
+      , (85, "otantecinc")
+      , (86, "otantesîs")
+      , (87, "otantesiet")
+      , (88, "otantevot")
+      , (89, "otantenûf")
+      , (90, "novante")
+      , (91, "novanteun")
+      , (92, "novantedoi")
+      , (93, "novantetrê")
+      , (94, "novantecuatri")
+      , (95, "novantecinc")
+      , (96, "novantesîs")
+      , (97, "novantesiet")
+      , (98, "novantevot")
+      , (99, "novantenûf")
+      , (100, "cent")
+      , (109, "cent e nûf")
+      , (110, "cent e dîs")
+      , (123, "cent e vincjetrê")
+      , (200, "dusinte")
+      , (230, "dusinte e trente")
+      , (234, "dusinte e trentecuatri")
+      , (300, "tresinte")
+      , (400, "cuatricent")
+      , (500, "cinccent")
+      , (600, "sîscent")
+      , (700, "sietcent")
+      , (800, "votcent")
+      , (900, "nûfcent")
+      , (999, "nûfcent e novantenûf")
+      , (1000, "mil")
+      , (1001, "mil e un")
+      , (1005, "mil e cinc")
+      , (1050, "mil e cincuante")
+      , (1100, "mil e cent")
+      , (1110, "mil cent e dîs")
+      , (1500, "mil e cinccent")
+      , (1550, "mil cinccent e cincuante")
+      , (2000, "doi mil")
+      , (2005, "doi mil e cinc")
+      , (2050, "doi mil e cincuante")
+      , (2500, "doi mil e cinccent")
+      , (2550, "doi mil cinccent e cincuante")
+      , (3000, "trê mil")
+      , (4000, "cuatri mil")
+      , (10000, "dîs mil")
+      , (12000, "dodis mil")
+      , (12005, "dodis mil e cinc")
+      , (12345, "dodis mil tresinte e cuarantecinc")
+      , (100000, "cent mil")
+      , (110000, "cent e dîs mil")
+      , (110010, "cent e dîs mil e dîs")
+      , (123456, "cent e vincjetrê mil cuatricent e cincuantesîs")
+      , (dec 6, "un milion")
+      , (2 ⋅ dec 6, "doi milions")
+      , (3 ⋅ dec 6, "trê milions")
+      , (10 ⋅ dec 6, "dîs milions")
+      , (dec 9, "un miliart")
+      , (2 ⋅ dec 9, "doi miliarts")
+      , (3 ⋅ dec 9, "trê miliarts")
+      ]
+    )
+  , ( "feminine"
+    , feminine defaultInflection
+    , [ (1, "une")
+      , (2, "dôs")
+      , (2 ⋅ dec 6, "dôs milions")
+      , (2 ⋅ dec 9, "dôs miliarts")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/GCF_MTQ/TestData.hs b/src-test/Text/Numeral/Language/GCF_MTQ/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/GCF_MTQ/TestData.hs
@@ -0,0 +1,205 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        gcf
+
+[@Native name@]     -
+
+[@English name@]    Antillean Creole of Martinique
+-}
+module Text.Numeral.Language.GCF_MTQ.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-antillean-creole-of-martinique/en/gcf-mtq/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "zéwo")
+      , (1, "yonn")
+      , (2, "dé")
+      , (3, "twa")
+      , (4, "kat")
+      , (5, "senk")
+      , (6, "sis")
+      , (7, "sèt")
+      , (8, "uit")
+      , (9, "nèf")
+      , (10, "dis")
+      , (11, "wonz")
+      , (12, "douz")
+      , (13, "trèz")
+      , (14, "katòz")
+      , (15, "tjenz")
+      , (16, "sèz")
+      , (17, "disèt")
+      , (18, "dizuit")
+      , (19, "diznèf")
+      , (20, "ven")
+      , (21, "ventéen")
+      , (22, "venndé")
+      , (23, "venntwa")
+      , (24, "vennkat")
+      , (25, "vennsenk")
+      , (26, "vennsis")
+      , (27, "vennsèt")
+      , (28, "vennuit")
+      , (29, "vennèf")
+      , (30, "trant")
+      , (31, "trantéen")
+      , (32, "tranndé")
+      , (33, "tranntwa")
+      , (34, "trannkat")
+      , (35, "trannsenk")
+      , (36, "trannsis")
+      , (37, "trannsèt")
+      , (38, "trantuit")
+      , (39, "trantnèf")
+      , (40, "karant")
+      , (41, "karantéen")
+      , (42, "karanndé")
+      , (43, "karanntwa")
+      , (44, "karannkat")
+      , (45, "karannsenk")
+      , (46, "karannsis")
+      , (47, "karannsèt")
+      , (48, "karantuit")
+      , (49, "karantnèf")
+      , (50, "senkant")
+      , (51, "senkantéen")
+      , (52, "senkanndé")
+      , (53, "senkanntwa")
+      , (54, "senkannkat")
+      , (55, "senkannsenk")
+      , (56, "senkannsis")
+      , (57, "senkannsèt")
+      , (58, "senkantuit")
+      , (59, "senkantnèf")
+      , (60, "swasant")
+      , (61, "swasantéen")
+      , (62, "swasanndé")
+      , (63, "swasanntwa")
+      , (64, "swasannkat")
+      , (65, "swasannsenk")
+      , (66, "swasannsis")
+      , (67, "swasannsèt")
+      , (68, "swasantuit")
+      , (69, "swasantnèf")
+      , (70, "swasanndis")
+      , (71, "swasannwonz")
+      , (72, "swasanndouz")
+      , (73, "swasanntrèz")
+      , (74, "swasannkatòz")
+      , (75, "swasanntjenz")
+      , (76, "swasannsèz")
+      , (77, "swasanndisèt")
+      , (78, "swasanndizuit")
+      , (79, "swasanndiznèf")
+      , (80, "katrèven")
+      , (81, "katrèventéen")
+      , (82, "katrèvenndé")
+      , (83, "katrèvenntwa")
+      , (84, "katrèvennkat")
+      , (85, "katrèvennsenk")
+      , (86, "katrèvennsis")
+      , (87, "katrèvennsèt")
+      , (88, "katrèvennuit")
+      , (89, "katrèvennèf")
+      , (90, "katrèvendis")
+      , (91, "katrèvenwonz")
+      , (92, "katrèvendouz")
+      , (93, "katrèventrèz")
+      , (94, "katrèvenkatòz")
+      , (95, "katrèventjenz")
+      , (96, "katrèvensèz")
+      , (97, "katrèvendisèt")
+      , (98, "katrèvendizuit")
+      , (99, "katrèvendiznèf")
+      , (100, "san")
+      , (101, "san-en")
+      , (102, "sandé")
+      , (103, "santwa")
+      , (104, "sankat")
+      , (105, "sansenk")
+      , (106, "sansis")
+      , (107, "sansèt")
+      , (108, "sanuit")
+      , (109, "sannèf")
+      , (110, "sandis")
+      , (123, "sanvenntwa")
+      , (200, "désan")
+      , (300, "twasan")
+      , (321, "twasanventéen")
+      , (400, "katsan")
+      , (500, "sensan")
+      , (600, "sisan")
+      , (700, "sètsan")
+      , (800, "uisan")
+      , (900, "nèfsan")
+      , (909, "nèfsannèf")
+      , (990, "nèfsankatrèvendis")
+      , (999, "nèfsankatrèvendiznèf")
+      , (1000, "mil")
+      , (1001, "mil yonn")
+      , (1008, "mil uit")
+      , (1234, "mil désantrannkat")
+      , (2000, "dé mil")
+      , (3000, "twa mil")
+      , (4000, "kat mil")
+      , (4321, "kat mil twasanventéen")
+      , (5000, "senk mil")
+      , (6000, "sis mil")
+      , (7000, "sèt mil")
+      , (8000, "uit mil")
+      , (9000, "nèf mil")
+      , (10000, "dimil")
+      , (12345, "douz mil twasankarannsenk")
+      , (20000, "ven mil")
+      , (30000, "trant mil")
+      , (40000, "karant mil")
+      , (50000, "senkant mil")
+      , (54321, "senkannkat mil twasanventéen")
+      , (60000, "swasant mil")
+      , (70000, "swasanndimil")
+      , (80000, "katrèven mil")
+      , (90000, "katrèvendimil")
+      , (100000, "san mil")
+      , (123456, "sanvenntwa mil katsansenkannsis")
+      , (200000, "désan mil")
+      , (300000, "twasan mil")
+      , (400000, "katsan mil")
+      , (500000, "sensan mil")
+      , (600000, "sisan mil")
+      , (654321, "sisansenkannkat mil twasanventéen")
+      , (700000, "sètsan mil")
+      , (800000, "uisan mil")
+      , (900000, "nèfsan mil")
+      , (1000000, "an milyon")
+      , (1000000000, "an milya")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/GIL/TestData.hs b/src-test/Text/Numeral/Language/GIL/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/GIL/TestData.hs
@@ -0,0 +1,225 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        gil
+
+[@ISO639-3@]        gil
+
+[@Native name@]     Taetae ni Kiribati
+
+[@English name@]    Gilbertese
+-}
+module Text.Numeral.Language.GIL.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-gilbertese/en/gil/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "akea")
+      , (1, "teuana")
+      , (2, "uoua")
+      , (3, "tenua")
+      , (4, "aua")
+      , (5, "nimaua")
+      , (6, "onoua")
+      , (7, "itua")
+      , (8, "wanua")
+      , (9, "ruaiwa")
+      , (10, "tebwina")
+      , (11, "tebwi ma teuana")
+      , (12, "tebwi ma uoua")
+      , (13, "tebwi ma tenua")
+      , (14, "tebwi ma aua")
+      , (15, "tebwi ma nimaua")
+      , (16, "tebwi ma onoua")
+      , (17, "tebwi ma itua")
+      , (18, "tebwi ma wanua")
+      , (19, "tebwi ma ruaiwa")
+      , (20, "uabwi")
+      , (21, "uabwi ma teuana")
+      , (22, "uabwi ma uoua")
+      , (23, "uabwi ma tenua")
+      , (24, "uabwi ma aua")
+      , (25, "uabwi ma nimaua")
+      , (26, "uabwi ma onoua")
+      , (27, "uabwi ma itua")
+      , (28, "uabwi ma wanua")
+      , (29, "uabwi ma ruaiwa")
+      , (30, "tenibwi")
+      , (31, "tenibwi ma teuana")
+      , (32, "tenibwi ma uoua")
+      , (33, "tenibwi ma tenua")
+      , (34, "tenibwi ma aua")
+      , (35, "tenibwi ma nimaua")
+      , (36, "tenibwi ma onoua")
+      , (37, "tenibwi ma itua")
+      , (38, "tenibwi ma wanua")
+      , (39, "tenibwi ma ruaiwa")
+      , (40, "abwi")
+      , (41, "abwi ma teuana")
+      , (42, "abwi ma uoua")
+      , (43, "abwi ma tenua")
+      , (44, "abwi ma aua")
+      , (45, "abwi ma nimaua")
+      , (46, "abwi ma onoua")
+      , (47, "abwi ma itua")
+      , (48, "abwi ma wanua")
+      , (49, "abwi ma ruaiwa")
+      , (50, "nimabwi")
+      , (51, "nimabwi ma teuana")
+      , (52, "nimabwi ma uoua")
+      , (53, "nimabwi ma tenua")
+      , (54, "nimabwi ma aua")
+      , (55, "nimabwi ma nimaua")
+      , (56, "nimabwi ma onoua")
+      , (57, "nimabwi ma itua")
+      , (58, "nimabwi ma wanua")
+      , (59, "nimabwi ma ruaiwa")
+      , (60, "onobwi")
+      , (61, "onobwi ma teuana")
+      , (62, "onobwi ma uoua")
+      , (63, "onobwi ma tenua")
+      , (64, "onobwi ma aua")
+      , (65, "onobwi ma nimaua")
+      , (66, "onobwi ma onoua")
+      , (67, "onobwi ma itua")
+      , (68, "onobwi ma wanua")
+      , (69, "onobwi ma ruaiwa")
+      , (70, "itibwi")
+      , (71, "itibwi ma teuana")
+      , (72, "itibwi ma uoua")
+      , (73, "itibwi ma tenua")
+      , (74, "itibwi ma aua")
+      , (75, "itibwi ma nimaua")
+      , (76, "itibwi ma onoua")
+      , (77, "itibwi ma itua")
+      , (78, "itibwi ma wanua")
+      , (79, "itibwi ma ruaiwa")
+      , (80, "wanibwi")
+      , (81, "wanibwi ma teuana")
+      , (82, "wanibwi ma uoua")
+      , (83, "wanibwi ma tenua")
+      , (84, "wanibwi ma aua")
+      , (85, "wanibwi ma nimaua")
+      , (86, "wanibwi ma onoua")
+      , (87, "wanibwi ma itua")
+      , (88, "wanibwi ma wanua")
+      , (89, "wanibwi ma ruaiwa")
+      , (90, "ruabwi")
+      , (91, "ruabwi ma teuana")
+      , (92, "ruabwi ma uoua")
+      , (93, "ruabwi ma tenua")
+      , (94, "ruabwi ma aua")
+      , (95, "ruabwi ma nimaua")
+      , (96, "ruabwi ma onoua")
+      , (97, "ruabwi ma itua")
+      , (98, "ruabwi ma wanua")
+      , (99, "ruabwi ma ruaiwa")
+      , (100, "tebubua")
+      , (101, "tebubua ao teuana")
+      , (102, "tebubua ao uoua")
+      , (103, "tebubua ao tenua")
+      , (104, "tebubua ao aua")
+      , (105, "tebubua ao nimaua")
+      , (106, "tebubua ao onoua")
+      , (107, "tebubua ao itua")
+      , (108, "tebubua ao wanua")
+      , (109, "tebubua ao ruaiwa")
+      , (110, "tebubua tebwina")
+      , (123, "tebubua uabwi ma tenua")
+      , (200, "uabubua")
+      , (300, "tenibubua")
+      , (321, "tenibubua uabwi ma teuana")
+      , (400, "abubua")
+      , (500, "nimabubua")
+      , (600, "onobubua")
+      , (700, "itibubua")
+      , (800, "wanibubua")
+      , (900, "ruabubua")
+      , (909, "ruabubua ao ruaiwa")
+      , (990, "ruabubua ruabwi")
+      , (999, "ruabubua ruabwi ma ruaiwa")
+      , (1000, "tengaa")
+      , (1001, "tengaa ao teuana")
+      , (1008, "tengaa ao wanua")
+      , (1234, "tengaa uabubua tenibwi ma aua")
+      , (2000, "uangaa")
+      , (3000, "teningaa")
+      , (4000, "angaa")
+      , (4321, "angaa tenibubua uabwi ma teuana")
+      , (5000, "nimangaa")
+      , (6000, "onongaa")
+      , (7000, "itingaa")
+      , (8000, "waniengaa")
+      , (9000, "ruangaa")
+      , (10000, "tebwina tengaa")
+      , (12345, "tebwi ma uoua tengaa tenibubua abwi ma nimaua")
+      , (20000, "uabwi tengaa")
+      , (30000, "tenibwi tengaa")
+      , (40000, "abwi tengaa")
+      , (50000, "nimabwi tengaa")
+      , (54321, "nimabwi ma aua tengaa tenibubua uabwi ma teuana")
+      , (60000, "onobwi tengaa")
+      , (70000, "itibwi tengaa")
+      , (80000, "wanibwi tengaa")
+      , (90000, "ruabwi tengaa")
+      , (100000, "tebubua tengaa")
+      , (123456, "tebubua uabwi ma tenua tengaa abubua nimabwi ma onoua")
+      , (200000, "uabubua tengaa")
+      , (300000, "tenibubua tengaa")
+      , (400000, "abubua tengaa")
+      , (500000, "nimabubua tengaa")
+      , (600000, "onobubua tengaa")
+      , (654321, "onobubua nimabwi ma aua tengaa tenibubua uabwi ma teuana")
+      , (700000, "itibubua tengaa")
+      , (800000, "wanibubua tengaa")
+      , (900000, "ruabubua tengaa")
+      , (1000000, "te mirion")
+      , (1000001, "te mirion, teuana")
+      , (1234567, "te mirion, uabubua tenibwi ma aua tengaa nimabubua onobwi ma itua")
+      , (2000000, "uoua te mirion")
+      , (3000000, "tenua te mirion")
+      , (4000000, "aua te mirion")
+      , (5000000, "nimaua te mirion")
+      , (6000000, "onoua te mirion")
+      , (7000000, "itua te mirion")
+      , (7654321, "itua te mirion, onobubua nimabwi ma aua tengaa tenibubua uabwi ma teuana")
+      , (8000000, "wanua te mirion")
+      , (9000000, "ruaiwa te mirion")
+      , (1000000000, "te birian")
+      , (1000000001, "te birian, teuana")
+      , (2000000000, "uoua te birian")
+      , (3000000000, "tenua te birian")
+      , (4000000000, "aua te birian")
+      , (5000000000, "nimaua te birian")
+      , (6000000000, "onoua te birian")
+      , (7000000000, "itua te birian")
+      , (8000000000, "wanua te birian")
+      , (9000000000, "ruaiwa te birian")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/GL/TestData.hs b/src-test/Text/Numeral/Language/GL/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/GL/TestData.hs
@@ -0,0 +1,235 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        gl
+
+[@ISO639-2@]        glg
+
+[@ISO639-3@]        glg
+
+[@Native name@]     Galego
+
+[@English name@]    Galician
+-}
+module Text.Numeral.Language.GL.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-galician/en/glg/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "cero")
+      , (1, "un")
+      , (2, "dous")
+      , (3, "tres")
+      , (4, "catro")
+      , (5, "cinco")
+      , (6, "seis")
+      , (7, "sete")
+      , (8, "oito")
+      , (9, "nove")
+      , (10, "dez")
+      , (11, "once")
+      , (12, "doce")
+      , (13, "trece")
+      , (14, "catorce")
+      , (15, "quince")
+      , (16, "dezaseis")
+      , (17, "dezasete")
+      , (18, "dezoito")
+      , (19, "dezanove")
+      , (20, "vinte")
+      , (21, "vinte e un")
+      , (22, "vinte e dous")
+      , (23, "vinte e tres")
+      , (24, "vinte e catro")
+      , (25, "vinte e cinco")
+      , (26, "vinte e seis")
+      , (27, "vinte e sete")
+      , (28, "vinte e oito")
+      , (29, "vinte e nove")
+      , (30, "trinta")
+      , (31, "trinta e un")
+      , (32, "trinta e dous")
+      , (33, "trinta e tres")
+      , (34, "trinta e catro")
+      , (35, "trinta e cinco")
+      , (36, "trinta e seis")
+      , (37, "trinta e sete")
+      , (38, "trinta e oito")
+      , (39, "trinta e nove")
+      , (40, "corenta")
+      , (41, "corenta e un")
+      , (42, "corenta e dous")
+      , (43, "corenta e tres")
+      , (44, "corenta e catro")
+      , (45, "corenta e cinco")
+      , (46, "corenta e seis")
+      , (47, "corenta e sete")
+      , (48, "corenta e oito")
+      , (49, "corenta e nove")
+      , (50, "cincuenta")
+      , (51, "cincuenta e un")
+      , (52, "cincuenta e dous")
+      , (53, "cincuenta e tres")
+      , (54, "cincuenta e catro")
+      , (55, "cincuenta e cinco")
+      , (56, "cincuenta e seis")
+      , (57, "cincuenta e sete")
+      , (58, "cincuenta e oito")
+      , (59, "cincuenta e nove")
+      , (60, "sesenta")
+      , (61, "sesenta e un")
+      , (62, "sesenta e dous")
+      , (63, "sesenta e tres")
+      , (64, "sesenta e catro")
+      , (65, "sesenta e cinco")
+      , (66, "sesenta e seis")
+      , (67, "sesenta e sete")
+      , (68, "sesenta e oito")
+      , (69, "sesenta e nove")
+      , (70, "setenta")
+      , (71, "setenta e un")
+      , (72, "setenta e dous")
+      , (73, "setenta e tres")
+      , (74, "setenta e catro")
+      , (75, "setenta e cinco")
+      , (76, "setenta e seis")
+      , (77, "setenta e sete")
+      , (78, "setenta e oito")
+      , (79, "setenta e nove")
+      , (80, "oitenta")
+      , (81, "oitenta e un")
+      , (82, "oitenta e dous")
+      , (83, "oitenta e tres")
+      , (84, "oitenta e catro")
+      , (85, "oitenta e cinco")
+      , (86, "oitenta e seis")
+      , (87, "oitenta e sete")
+      , (88, "oitenta e oito")
+      , (89, "oitenta e nove")
+      , (90, "noventa")
+      , (91, "noventa e un")
+      , (92, "noventa e dous")
+      , (93, "noventa e tres")
+      , (94, "noventa e catro")
+      , (95, "noventa e cinco")
+      , (96, "noventa e seis")
+      , (97, "noventa e sete")
+      , (98, "noventa e oito")
+      , (99, "noventa e nove")
+      , (100, "cen")
+      , (101, "cento un")
+      , (102, "cento dous")
+      , (103, "cento tres")
+      , (104, "cento catro")
+      , (105, "cento cinco")
+      , (106, "cento seis")
+      , (107, "cento sete")
+      , (108, "cento oito")
+      , (109, "cento nove")
+      , (110, "cento dez")
+      , (123, "cento vinte e tres")
+      , (200, "douscentos")
+      , (300, "trescentos")
+      , (321, "trescentos e vinte e un")
+      , (400, "catrocentos")
+      , (500, "cincocentos")
+      , (600, "seiscentos")
+      , (700, "setecentos")
+      , (800, "oitocentos")
+      , (900, "novecentos")
+      , (909, "novecentos e nove")
+      , (990, "novecentos e noventa")
+      , (999, "novecentos e noventa e nove")
+      , (1000, "mil")
+      , (1001, "mil e un")
+      , (1008, "mil e oito")
+      , (1234, "mil douscentos e trinta e catro")
+      , (2000, "dous mil")
+      , (3000, "tres mil")
+      , (4000, "catro mil")
+      , (4321, "catro mil trescentos e vinte e un")
+      , (5000, "cinco mil")
+      , (6000, "seis mil")
+      , (7000, "sete mil")
+      , (8000, "oito mil")
+      , (9000, "nove mil")
+      , (10000, "dez mil")
+      , (12345, "doce mil trescentos e corenta e cinco")
+      , (20000, "vinte mil")
+      , (30000, "trinta mil")
+      , (40000, "corenta mil")
+      , (50000, "cincuenta mil")
+      , (54321, "cincuenta e catro mil trescentos e vinte e un")
+      , (60000, "sesenta mil")
+      , (70000, "setenta mil")
+      , (80000, "oitenta mil")
+      , (90000, "noventa mil")
+      , (100000, "cen mil")
+      , (123456, "cento vinte e tres mil catrocentos e cincuenta e seis")
+      , (200000, "douscentos mil")
+      , (300000, "trescentos mil")
+      , (400000, "catrocentos mil")
+      , (500000, "cincocentos mil")
+      , (600000, "seiscentos mil")
+      , (654321, "seiscentos e cincuenta e catro mil trescentos e vinte e un")
+      , (700000, "setecentos mil")
+      , (800000, "oitocentos mil")
+      , (900000, "novecentos mil")
+      , (1000000, "un milhom")
+      , (1000001, "un milhom e un")
+      , (1234567, "un milhom douscentos e trinta e catro mil cincocentos e sesenta e sete")
+      , (2000000, "dous milhom")
+      , (3000000, "tres milhom")
+      , (4000000, "catro milhom")
+      , (5000000, "cinco milhom")
+      , (6000000, "seis milhom")
+      , (7000000, "sete milhom")
+      , (7654321, "sete milhom seiscentos e cincuenta e catro mil trescentos e vinte e un")
+      , (8000000, "oito milhom")
+      , (9000000, "nove milhom")
+      , (1000000000, "un bilhom")
+      , (1000000001, "un bilhom e un")
+      , (2000000000, "dous bilhom")
+      , (3000000000, "tres bilhom")
+      , (4000000000, "catro bilhom")
+      , (5000000000, "cinco bilhom")
+      , (6000000000, "seis bilhom")
+      , (7000000000, "sete bilhom")
+      , (8000000000, "oito bilhom")
+      , (9000000000, "nove bilhom")
+      , (1000000000000, "un trilhom")
+      , (1000000000001, "un trilhom e un")
+      , (2000000000000, "dous trilhom")
+      , (3000000000000, "tres trilhom")
+      , (4000000000000, "catro trilhom")
+      , (5000000000000, "cinco trilhom")
+      , (6000000000000, "seis trilhom")
+      , (7000000000000, "sete trilhom")
+      , (8000000000000, "oito trilhom")
+      , (9000000000000, "nove trilhom")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/GSW/TestData.hs b/src-test/Text/Numeral/Language/GSW/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/GSW/TestData.hs
@@ -0,0 +1,148 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        gse
+
+[@ISO639-3@]        gse
+
+[@Native name@]     Schwyzerdütsch
+
+[@English name@]    Swiss German
+-}
+
+module Text.Numeral.Language.GSW.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-swiss-german/en/gsw-che/
+-}
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "eis")
+      , (2, "zwöi")
+      , (3, "drü")
+      , (4, "vier")
+      , (5, "füf")
+      , (6, "sächs")
+      , (7, "sibe")
+      , (8, "acht")
+      , (9, "nüün")
+      , (10, "zäh")
+      , (11, "euf")
+      , (12, "zwüof")
+      , (13, "dryzäh")
+      , (14, "vierzäh")
+      , (15, "füfzäh")
+      , (16, "sächszäh")
+      , (17, "sibezäh")
+      , (18, "achtzäh")
+      , (19, "nüünzäh")
+      , (20, "zwänzg")
+      , (21, "einezwänzg")
+      , (22, "zwöiezwänzg")
+      , (23, "drüezwänzg")
+      , (24, "vierezwänzg")
+      , (25, "füfezwänzg")
+      , (26, "sächsezwänzg")
+      , (27, "sibenezwänzg")
+      , (28, "achtezwänzg")
+      , (29, "nünezwänzg")
+      , (30, "dryssg")
+      -- , (31, "")
+      -- , (32, "")
+      -- , (33, "")
+      -- , (34, "")
+      , (35, "füfedryssg")
+      -- , (36, "")
+      -- , (37, "")
+      -- , (38, "")
+      -- , (39, "")
+      , (40, "vierzg")
+      -- , (41, "")
+      -- , (42, "")
+      -- , (43, "")
+      -- , (44, "")
+      -- , (45, "")
+      -- , (46, "")
+      -- , (47, "")
+      -- , (48, "")
+      -- , (49, "")
+      , (50, "füfzg")
+      , (51, "einefüfzg")
+      -- , (52, "")
+      -- , (53, "")
+      -- , (54, "")
+      -- , (55, "")
+      -- , (56, "")
+      -- , (57, "")
+      -- , (58, "")
+      -- , (59, "")
+      , (60, "sëchzg")
+      -- , (61, "")
+      -- , (62, "")
+      -- , (63, "")
+      -- , (64, "")
+      -- , (65, "")
+      -- , (66, "")
+      -- , (67, "")
+      -- , (68, "")
+      -- , (69, "")
+      , (70, "sibezg")
+      -- , (71, "")
+      , (72, "zwöiesibezg")
+      -- , (73, "")
+      -- , (74, "")
+      -- , (75, "")
+      -- , (76, "")
+      -- , (77, "")
+      -- , (78, "")
+      -- , (79, "")
+      , (80, "achzg")
+      -- , (81, "")
+      -- , (82, "")
+      -- , (83, "")
+      -- , (84, "")
+      -- , (85, "")
+      -- , (86, "")
+      -- , (87, "")
+      -- , (88, "")
+      -- , (89, "")
+      , (90, "nüünzg")
+      -- , (91, "")
+      -- , (92, "")
+      -- , (93, "")
+      -- , (94, "")
+      -- , (95, "")
+      -- , (96, "")
+      , (97, "sibenenüünzg")
+      -- , (98, "")
+      -- , (99, "")
+      , (100, "hundert")
+      , (101, "hundertundäis")
+      , (102, "hundertzwöi")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/GV/TestData.hs b/src-test/Text/Numeral/Language/GV/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/GV/TestData.hs
@@ -0,0 +1,158 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        gv
+
+[@ISO639-2@]        glv
+
+[@ISO639-3@]        glv
+
+[@Native name@]     Gaelg
+
+[@English name@]    Manx
+-}
+
+module Text.Numeral.Language.GV.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.sf.airnet.ne.jp/~ts/language/number/manx.html
+  http://www.gaelg.iofm.net/LESSONS/P/P19.html
+  http://www.gaelg.iofm.net/LESSONS/mona/Lessons.pdf
+-}
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "nane")
+      , (2, "jees")
+      , (3, "tree")
+      , (4, "kiare")
+      , (5, "queig")
+      , (6, "shey")
+      , (7, "shiaght")
+      , (8, "hoght")
+      , (9, "nuy")
+      , (10, "jeih")
+      , (11, "nane-jeig")
+      , (12, "daa-yeig")
+      , (13, "tree-jeig")
+      , (14, "kiare-jeig")
+      , (15, "queig-jeig")
+      , (16, "shey-jeig")
+      , (17, "shiaght-jeig")
+      , (18, "hoght-jeig")
+      , (19, "nuy-jeig")
+      , (20, "feed")
+      , (21, "nane as feed")
+      , (22, "jees as feed")
+      , (23, "tree as feed")
+      , (24, "kiare as feed")
+      , (25, "queig as feed")
+      , (26, "shey as feed")
+      , (27, "shiaght as feed")
+      , (28, "hoght as feed")
+      , (29, "nuy as feed")
+      , (30, "jeih as feed")
+      , (31, "nane-jeig as feed")
+      , (32, "daa-yeig as feed")
+      , (33, "tree-jeig as feed")
+      , (34, "kiare-jeig as feed")
+      , (35, "queig-jeig as feed")
+      , (36, "shey-jeig as feed")
+      , (37, "shiaght-jeig as feed")
+      , (38, "hoght-jeig as feed")
+      , (39, "nuy-jeig as feed")
+      , (40, "daeed")
+      , (41, "nane as daeed")
+      , (42, "jees as daeed")
+      , (43, "tree as daeed")
+      , (44, "kiare as daeed")
+      , (45, "queig as daeed")
+      , (46, "shey as daeed")
+      , (47, "shiaght as daeed")
+      , (48, "hoght as daeed")
+      , (49, "nuy as daeed")
+      , (50, "jeih as daeed")
+      , (51, "nane-jeig as daeed")
+      , (52, "daa-yeig as daeed")
+      , (53, "tree-jeig as daeed")
+      , (54, "kiare-jeig as daeed")
+      , (55, "queig-jeig as daeed")
+      , (56, "shey-jeig as daeed")
+      , (57, "shiaght-jeig as daeed")
+      , (58, "hoght-jeig as daeed")
+      , (59, "nuy-jeig as daeed")
+      , (60, "tree feed")
+      , (61, "tree feed as nane")
+      , (62, "tree feed as jees")
+      , (63, "tree feed as tree")
+      , (64, "tree feed as kiare")
+      , (65, "tree feed as queig")
+      , (66, "tree feed as shey")
+      , (67, "tree feed as shiaght")
+      , (68, "tree feed as hoght")
+      , (69, "tree feed as nuy")
+      , (70, "tree feed as jeih")
+      , (71, "tree feed as nane-jeig")
+      , (72, "tree feed as daa-yeig")
+      , (73, "tree feed as tree-jeig")
+      , (74, "tree feed as kiare-jeig")
+      , (75, "tree feed as queig-jeig")
+      , (76, "tree feed as shey-jeig")
+      , (77, "tree feed as shiaght-jeig")
+      , (78, "tree feed as hoght-jeig")
+      , (79, "tree feed as nuy-jeig")
+      , (80, "kiare feed")
+      , (81, "kiare feed as nane")
+      , (82, "kiare feed as jees")
+      , (83, "kiare feed as tree")
+      , (84, "kiare feed as kiare")
+      , (85, "kiare feed as queig")
+      , (86, "kiare feed as shey")
+      , (87, "kiare feed as shiaght")
+      , (88, "kiare feed as hoght")
+      , (89, "kiare feed as nuy")
+      , (90, "kiare feed as jeih")
+      , (91, "kiare feed as nane-jeig")
+      , (92, "kiare feed as daa-yeig")
+      , (93, "kiare feed as tree-jeig")
+      , (94, "kiare feed as kiare-jeig")
+      , (95, "kiare feed as queig-jeig")
+      , (96, "kiare feed as shey-jeig")
+      , (97, "kiare feed as shiaght-jeig")
+      , (98, "kiare feed as hoght-jeig")
+      , (99, "kiare feed as nuy-jeig")
+      , (100, "keead")
+      , (200, "daa cheead")
+      , (300, "tree cheead")
+      , (400, "kiare cheead")
+      , (500, "queig cheead")
+      , (600, "shey cheead")
+      , (700, "shiaght cheead")
+      , (800, "hoght cheead")
+      , (900, "nuy cheead")
+      , (1000, "thousane")
+      -- , (dec 6, "jeih cheead thousane")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/HAI/TestData.hs b/src-test/Text/Numeral/Language/HAI/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/HAI/TestData.hs
@@ -0,0 +1,228 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        hai
+
+[@ISO639-3@]        hai
+
+[@Native name@]     X̲aat Kíl
+
+[@English name@]    Haida
+-}
+module Text.Numeral.Language.HAI.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-haida/en/hai/
+  http://www.haidalanguage.org/phrases/numbers.html
+
+'guu' means 'less'
+'waak' means 'add on'
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "sgwáansang")
+      , (2, "sdáng")
+      , (3, "hlgúnahl")
+      , (4, "stánsang")
+      , (5, "tléihl")
+      , (6, "tla’únhl")
+      , (7, "jagwaa")
+      , (8, "sdáansaangaa")
+      , (9, "tláahlsgwáansangguu") -- ten minus one
+      , (10, "tláahl")
+      , (11, "tláahl wáak sgwáansang")
+      , (12, "tláahl wáak sdáng")
+      , (13, "tláahl wáak hlgúnahl")
+      , (14, "tláahl wáak stánsang")
+      , (15, "tláahl wáak tléihl")
+      , (16, "tláahl wáak tla’únhl")
+      , (17, "tláahl wáak jagwaa")
+      , (18, "tláahl wáak sdáansaangaa")
+      , (19, "tláahl wáak tláahlsgwáansangguu")
+      , (20, "lagwa uu sgwáansang")
+      , (21, "lagwa uu sgwáansang wáak sgwáansang")
+      , (22, "lagwa uu sgwáansang wáak sdáng")
+      , (23, "lagwa uu sgwáansang wáak hlgúnahl")
+      , (24, "lagwa uu sgwáansang wáak stánsang")
+      , (25, "lagwa uu sgwáansang wáak tléihl")
+      , (26, "lagwa uu sgwáansang wáak tla’únhl")
+      , (27, "lagwa uu sgwáansang wáak jagwaa")
+      , (28, "lagwa uu sgwáansang wáak sdáansaangaa")
+      , (29, "lagwa uu sgwáansang wáak tláahlsgwáansangguu")
+      , (30, "tlaalee hlgúnahl")
+      , (31, "tlaalee hlgúnahl wáak sgwáansang")
+      , (32, "tlaalee hlgúnahl wáak sdáng")
+      , (33, "tlaalee hlgúnahl wáak hlgúnahl")
+      , (34, "tlaalee hlgúnahl wáak stánsang")
+      , (35, "tlaalee hlgúnahl wáak tléihl")
+      , (36, "tlaalee hlgúnahl wáak tla’únhl")
+      , (37, "tlaalee hlgúnahl wáak jagwaa")
+      , (38, "tlaalee hlgúnahl wáak sdáansaangaa")
+      , (39, "tlaalee hlgúnahl wáak tláahlsgwáansangguu")
+      , (40, "lagwa uu sdáng")
+      , (41, "lagwa uu sdáng wáak sgwáansang")
+      , (42, "lagwa uu sdáng wáak sdáng")
+      , (43, "lagwa uu sdáng wáak hlgúnahl")
+      , (44, "lagwa uu sdáng wáak stánsang")
+      , (45, "lagwa uu sdáng wáak tléihl")
+      , (46, "lagwa uu sdáng wáak tla’únhl")
+      , (47, "lagwa uu sdáng wáak jagwaa")
+      , (48, "lagwa uu sdáng wáak sdáansaangaa")
+      , (49, "lagwa uu sdáng wáak tláahlsgwáansangguu")
+      , (50, "tlaalee tléihl")
+      , (51, "tlaalee tléihl wáak sgwáansang")
+      , (52, "tlaalee tléihl wáak sdáng")
+      , (53, "tlaalee tléihl wáak hlgúnahl")
+      , (54, "tlaalee tléihl wáak stánsang")
+      , (55, "tlaalee tléihl wáak tléihl")
+      , (56, "tlaalee tléihl wáak tla’únhl")
+      , (57, "tlaalee tléihl wáak jagwaa")
+      , (58, "tlaalee tléihl wáak sdáansaangaa")
+      , (59, "tlaalee tléihl wáak tláahlsgwáansangguu")
+      , (60, "lagwa uu hlgúnahl")
+      , (61, "lagwa uu hlgúnahl wáak sgwáansang")
+      , (62, "lagwa uu hlgúnahl wáak sdáng")
+      , (63, "lagwa uu hlgúnahl wáak hlgúnahl")
+      , (64, "lagwa uu hlgúnahl wáak stánsang")
+      , (65, "lagwa uu hlgúnahl wáak tléihl")
+      , (66, "lagwa uu hlgúnahl wáak tla’únhl")
+      , (67, "lagwa uu hlgúnahl wáak jagwaa")
+      , (68, "lagwa uu hlgúnahl wáak sdáansaangaa")
+      , (69, "lagwa uu hlgúnahl wáak tláahlsgwáansangguu")
+      , (70, "tlaalee jagwaa")
+      , (71, "tlaalee jagwaa wáak sgwáansang")
+      , (72, "tlaalee jagwaa wáak sdáng")
+      , (73, "tlaalee jagwaa wáak hlgúnahl")
+      , (74, "tlaalee jagwaa wáak stánsang")
+      , (75, "tlaalee jagwaa wáak tléihl")
+      , (76, "tlaalee jagwaa wáak tla’únhl")
+      , (77, "tlaalee jagwaa wáak jagwaa")
+      , (78, "tlaalee jagwaa wáak sdáansaangaa")
+      , (79, "tlaalee jagwaa wáak tláahlsgwáansangguu")
+      , (80, "lagwa uu sdáansaangaa")
+      , (81, "lagwa uu sdáansaangaa wáak sgwáansang")
+      , (82, "lagwa uu sdáansaangaa wáak sdáng")
+      , (83, "lagwa uu sdáansaangaa wáak hlgúnahl")
+      , (84, "lagwa uu sdáansaangaa wáak stánsang")
+      , (85, "lagwa uu sdáansaangaa wáak tléihl")
+      , (86, "lagwa uu sdáansaangaa wáak tla’únhl")
+      , (87, "lagwa uu sdáansaangaa wáak jagwaa")
+      , (88, "lagwa uu sdáansaangaa wáak sdáansaangaa")
+      , (89, "lagwa uu sdáansaangaa wáak tláahlsgwáansangguu")
+      , (90, "tlaalee tláahlsgwáansangguu")
+      , (91, "tlaalee tláahlsgwáansangguu wáak sgwáansang")
+      , (92, "tlaalee tláahlsgwáansangguu wáak sdáng")
+      , (93, "tlaalee tláahlsgwáansangguu wáak hlgúnahl")
+      , (94, "tlaalee tláahlsgwáansangguu wáak stánsang")
+      , (95, "tlaalee tláahlsgwáansangguu wáak tléihl")
+      , (96, "tlaalee tláahlsgwáansangguu wáak tla’únhl")
+      , (97, "tlaalee tláahlsgwáansangguu wáak jagwaa")
+      , (98, "tlaalee tláahlsgwáansangguu wáak sdáansaangaa")
+      , (99, "tlaalee tláahlsgwáansangguu wáak tláahlsgwáansangguu")
+      , (100, "lagwa uu tléihl")
+      , (101, "lagwa uu tléihl sgwáansang")
+      , (102, "lagwa uu tléihl sdáng")
+      , (103, "lagwa uu tléihl hlgúnahl")
+      , (104, "lagwa uu tléihl stánsang")
+      , (105, "lagwa uu tléihl tléihl")
+      , (106, "lagwa uu tléihl tla’únhl")
+      , (107, "lagwa uu tléihl jagwaa")
+      , (108, "lagwa uu tléihl sdáansaangaa")
+      , (109, "lagwa uu tléihl tláahlsgwáansangguu")
+      , (110, "lagwa uu tléihl tláahl")
+      , (123, "lagwa uu tléihl lagwa uu sgwáansang wáak hlgúnahl")
+      , (200, "lagwa uu tláahl")
+      , (300, "lagwa uu tláahl wáak lagwa uu tléihl")
+      , (321, "lagwa uu tláahl wáak lagwa uu tléihl lagwa uu sgwáansang wáak sgwáansang")
+      , (400, "lagwa uu tlaalee sdáng")
+      , (500, "lagwa uu tlaalee sdáng wáak lagwa uu tléihl")
+      , (600, "lagwa uu tlaalee tléihl")
+      , (700, "lagwa uu tlaalee wáak lagwa uu tléihl")
+      , (800, "lagwa uu tlaalee sdáansaangaa")
+      , (900, "lagwa uu tlaalee sdáansaangaa wáak lagwa uu tléihl")
+      , (909, "lagwa uu tlaalee sdáansaangaa wáak lagwa uu tléihl tláahlsgwáansangguu")
+      , (990, "lagwa uu tlaalee sdáansaangaa wáak lagwa uu tléihl tlaalee tláahlsgwáansangguu")
+      , (999, "lagwa uu tlaalee sdáansaangaa wáak lagwa uu tléihl tlaalee tláahlsgwáansangguu wáak tláahlsgwáansangguu")
+      , (1000, "lagwa uu tlaalee tléihl")
+      , (1001, "lagwa uu tlaalee tléihl sgwáansang")
+      , (1008, "lagwa uu tlaalee tléihl sdáansaangaa")
+      , (1234, "lagwa uu tlaalee tléihl lagwa uu tláahl tlaalee hlgúnahl wáak stánsang")
+      , (2000, "lagwa uu tlaalee tléihl wáak sdáng")
+      , (3000, "lagwa uu tlaalee tléihl wáak hlgúnahl")
+      , (4000, "lagwa uu tlaalee tléihl wáak stánsang")
+      , (4321, "lagwa uu tlaalee tléihl wáak stánsang lagwa uu tláahl wáak lagwa uu tléihl lagwa uu sgwáansang wáak sgwáansang")
+      , (5000, "lagwa uu tlaalee tléihl wáak tléihl")
+      , (6000, "lagwa uu tlaalee tléihl wáak tla’únhl")
+      , (7000, "lagwa uu tlaalee tléihl wáak jagwaa")
+      , (8000, "lagwa uu tlaalee tléihl wáak sdáansaangaa")
+      , (9000, "lagwa uu tlaalee tléihl wáak tláahlsgwáansangguu")
+      , (10000, "lagwa uu tlaalee tléihl wáak tláahl")
+      , (12345, "tláahl wáak lagwa uu tlaalee tléihl wáak sdáng lagwa uu tláahl wáak lagwa uu tléihl lagwa uu sdáng wáak tléihl")
+      , (20000, "lagwa uu lagwa uu tlaalee tléihl")
+      , (30000, "tlaalee lagwa uu tlaalee tléihl wáak hlgúnahl")
+      , (40000, "lagwa uu lagwa uu tlaalee tléihl wáak sdáng")
+      , (50000, "tlaalee lagwa uu tlaalee tléihl wáak tléihl")
+      , (54321, "tlaalee tléihl wáak lagwa uu tlaalee tléihl wáak stánsang lagwa uu tláahl wáak lagwa uu tléihl lagwa uu sgwáansang wáak sgwáansang")
+      , (60000, "lagwa uu lagwa uu tlaalee tléihl wáak hlgúnahl")
+      , (70000, "tlaalee lagwa uu tlaalee tléihl wáak jagwaa")
+      , (80000, "lagwa uu lagwa uu tlaalee tléihl wáak sdáansaangaa")
+      , (90000, "tlaalee lagwa uu tlaalee tléihl wáak tláahlsgwáansangguu")
+      , (100000, "lagwa uu taalee kwan tláahl wáak lagwa uu tléihl")
+      , (123456, "lagwa uu tléihl lagwa uu sgwáansang wáak lagwa uu tlaalee tléihl wáak hlgúnahl lagwa uu tlaalee sdáng tlaalee tléihl wáak tla’únhl")
+      , (200000, "lagwa uu lagwa uu tlaalee tléihl wáak tláahl")
+      , (300000, "lagwa uu tláahl wáak lagwa uu taalee kwan tláahl wáak lagwa uu tléihl")
+      , (400000, "lagwa uu tlaalee lagwa uu tlaalee tléihl wáak sdáng")
+      , (500000, "lagwa uu tlaalee sdáng wáak lagwa uu taalee kwan tláahl wáak lagwa uu tléihl")
+      , (600000, "lagwa uu tlaalee lagwa uu tlaalee tléihl wáak tléihl")
+      , (654321, "lagwa uu tlaalee tléihl tlaalee tléihl wáak lagwa uu tlaalee tléihl wáak stánsang lagwa uu tláahl wáak lagwa uu tléihl lagwa uu sgwáansang wáak sgwáansang")
+      , (700000, "lagwa uu tlaalee wáak lagwa uu taalee kwan tláahl wáak lagwa uu tléihl")
+      , (800000, "lagwa uu tlaalee lagwa uu tlaalee tléihl wáak sdáansaangaa")
+      , (900000, "lagwa uu tlaalee sdáansaangaa wáak lagwa uu taalee kwan tláahl wáak lagwa uu tléihl")
+      , (1000000, "lagwa uu tlaalee kwan")
+      , (1000001, "lagwa uu tlaalee kwan sgwáansang")
+      , (1234567, "lagwa uu tlaalee kwan lagwa uu tláahl tlaalee hlgúnahl wáak lagwa uu tlaalee tléihl wáak stánsang lagwa uu tlaalee sdáng wáak lagwa uu tléihl lagwa uu hlgúnahl wáak jagwaa")
+      , (2000000, "sdáng lagwa uu tlaalee kwan")
+      , (3000000, "hlgúnahl lagwa uu tlaalee kwan")
+      , (4000000, "stánsang lagwa uu tlaalee kwan")
+      , (5000000, "tléihl lagwa uu tlaalee kwan")
+      , (6000000, "tla’únhl lagwa uu tlaalee kwan")
+      , (7000000, "jagwaa lagwa uu tlaalee kwan")
+      , (7654321, "jagwaa lagwa uu tlaalee kwan lagwa uu tlaalee tléihl tlaalee tléihl wáak lagwa uu tlaalee tléihl wáak stánsang lagwa uu tláahl wáak lagwa uu tléihl lagwa uu sgwáansang wáak sgwáansang")
+      , (8000000, "sdáansaangaa lagwa uu tlaalee kwan")
+      , (9000000, "tláahlsgwáansangguu lagwa uu tlaalee kwan")
+      , (1000000000, "lagwa uu tlaalee kwan wáak lagwa uu tlaalee tléihl")
+      , (1000000001, "lagwa uu tlaalee kwan wáak lagwa uu tlaalee tléihl sgwáansang")
+      , (2000000000, "sdáng lagwa uu tlaalee kwan wáak lagwa uu tlaalee tléihl")
+      , (3000000000, "hlgúnahl lagwa uu tlaalee kwan wáak lagwa uu tlaalee tléihl")
+      , (4000000000, "stánsang lagwa uu tlaalee kwan wáak lagwa uu tlaalee tléihl")
+      , (5000000000, "tléihl lagwa uu tlaalee kwan wáak lagwa uu tlaalee tléihl")
+      , (6000000000, "tla’únhl lagwa uu tlaalee kwan wáak lagwa uu tlaalee tléihl")
+      , (7000000000, "jagwaa lagwa uu tlaalee kwan wáak lagwa uu tlaalee tléihl")
+      , (8000000000, "sdáansaangaa lagwa uu tlaalee kwan wáak lagwa uu tlaalee tléihl")
+      , (9000000000, "tláahlsgwáansangguu lagwa uu tlaalee kwan wáak lagwa uu tlaalee tléihl")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/HE/TestData.hs b/src-test/Text/Numeral/Language/HE/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/HE/TestData.hs
@@ -0,0 +1,315 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        he
+
+[@ISO639-2@]        heb
+
+[@ISO639-3@]        heb
+
+[@Native name@]     עִבְרִית
+
+[@English name@]    Modern Hebrew
+-}
+
+module Text.Numeral.Language.HE.TestData
+  ( cardinals
+  ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Grammar
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  E-mail by Yitzchak Gale.
+  http://www.hebrew4christians.com/Grammar/Unit_Eight/Cardinal_Numbers/cardinal_numbers.html
+-}
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "feminine"
+    , feminine defaultInflection
+    , [ (0, "אפס")
+      , (1, "אחת")
+      , (2, "שתיים") -- Connecting form: "שתי"
+      , (3, "שלוש")
+      , (4, "ארבע")
+      , (5, "חמש")
+      , (6, "שש")
+      , (7, "שבע")
+      , (8, "שמונה")
+      , (9, "תשע")
+      , (10, "עשר")
+      , (11, "אחת עשרה")
+      , (12, "שתים עשרה")
+      , (13, "שלוש עשרה")
+      , (14, "ארבע עשרה")
+      , (15, "חמש עשרה")
+      , (16, "שש עשרה")
+      , (17, "שבע עשרה")
+      , (18, "שמונה עשרה")
+      , (19, "תשע עשרה")
+      , (20, "עשרים")
+      , (21, "עשרים ואחת")
+      , (22, "עשרים ושתיים")
+      , (23, "עשרים ושלוש")
+      , (24, "עשרים וארבע")
+      , (25, "עשרים וחמש")
+      , (26, "עשרים ושש")
+      , (27, "עשרים ושבע")
+      , (28, "עשרים ושמונה")
+      , (29, "עשרים ותשע")
+      , (30, "שלושים")
+      , (31, "שלושים ואחת")
+      , (32, "שלושים ושתיים")
+      , (33, "שלושים ושלוש")
+      , (34, "שלושים וארבע")
+      , (35, "שלושים וחמש")
+      , (36, "שלושים ושש")
+      , (37, "שלושים ושבע")
+      , (38, "שלושים ושמונה")
+      , (39, "שלושים ותשע")
+      , (40, "ארבעים")
+      , (41, "ארבעים ואחת")
+      , (42, "ארבעים ושתיים")
+      , (43, "ארבעים ושלוש")
+      , (44, "ארבעים וארבע")
+      , (45, "ארבעים וחמש")
+      , (46, "ארבעים ושש")
+      , (47, "ארבעים ושבע")
+      , (48, "ארבעים ושמונה")
+      , (49, "ארבעים ותשע")
+      , (50, "חמישים")
+      , (51, "חמישים ואחת")
+      , (52, "חמישים ושתיים")
+      , (53, "חמישים ושלוש")
+      , (54, "חמישים וארבע")
+      , (55, "חמישים וחמש")
+      , (56, "חמישים ושש")
+      , (57, "חמישים ושבע")
+      , (58, "חמישים ושמונה")
+      , (59, "חמישים ותשע")
+      , (60, "ששים")
+      , (61, "ששים ואחת")
+      , (62, "ששים ושתיים")
+      , (63, "ששים ושלוש")
+      , (64, "ששים וארבע")
+      , (65, "ששים וחמש")
+      , (66, "ששים ושש")
+      , (67, "ששים ושבע")
+      , (68, "ששים ושמונה")
+      , (69, "ששים ותשע")
+      , (70, "שבעים")
+      , (71, "שבעים ואחת")
+      , (72, "שבעים ושתיים")
+      , (73, "שבעים ושלוש")
+      , (74, "שבעים וארבע")
+      , (75, "שבעים וחמש")
+      , (76, "שבעים ושש")
+      , (77, "שבעים ושבע")
+      , (78, "שבעים ושמונה")
+      , (79, "שבעים ותשע")
+      , (80, "שמונים")
+      , (81, "שמונים ואחת")
+      , (82, "שמונים ושתיים")
+      , (83, "שמונים ושלוש")
+      , (84, "שמונים וארבע")
+      , (85, "שמונים וחמש")
+      , (86, "שמונים ושש")
+      , (87, "שמונים ושבע")
+      , (88, "שמונים ושמונה")
+      , (89, "שמונים ותשע")
+      , (90, "תשעים")
+      , (91, "תשעים ואחת")
+      , (92, "תשעים ושתיים")
+      , (93, "תשעים ושלוש")
+      , (94, "תשעים וארבע")
+      , (95, "תשעים וחמש")
+      , (96, "תשעים ושש")
+      , (97, "תשעים ושבע")
+      , (98, "תשעים ושמונה")
+      , (99, "תשעים ותשע")
+      , (100, "מאה")
+      , (101, "מאה ואחת")
+      , (110, "מאה ועשר")
+      , (111, "מאה אחת עשרה")
+      , (123, "מאה עשרים ושלוש")
+      , (144, "מאה ארבעים וארבע")
+      , (199, "מאה תשעים ותשע")
+      , (200, "מאתיים")
+      , (299, "מאתיים תשעים ותשע")
+      , (300, "שלוש מאות")
+      , (400, "ארבע מאות")
+      , (900, "תשע מאות")
+      , (1000, "אלף")
+      , (1999, "אלף תשע מאות תשעים ותשע")
+      , (2000, "אלפיים")
+      , (2999, "אלפיים תשע מאות תשעים ותשע")
+      , (3000, "שלושת אלפים")
+      , (3110, "שלושת אלפים מאה ועשר")
+      , (4000, "ארבעת אלפים")
+      , (5000, "חמשת אלפים")
+      , (6000, "ששת אלפים")
+      , (7000, "שבעת אלפים")
+      , (8000, "שמונת אלפים")
+      , (9000, "תשעת אלפים")
+      , (10000, "עשרת אלפים")
+      , (11000, "אחד עשר אלף")
+      , (12000, "שנים עשר אלף")
+      , (dec 5, "מאה אלף")
+      , (dec 6, "מיליון")
+      , (dec 9, "מיליארד")
+      ]
+    )
+  , ( "masculine"
+    , masculine defaultInflection
+    , [ (0, "אפס")
+      , (1, "אחד")
+      , (2, "שניים") -- Connecting form: "שני"
+      , (3, "שלושה")
+      , (4, "ארבעה")
+      , (5, "חמישה")
+      , (6, "שישה")
+      , (7, "שבעה")
+      , (8, "שמונה")
+      , (9, "תשעה")
+      , (10, "עשרה")
+      , (11, "אחד עשר")
+      , (12, "שנים עשר")
+      , (13, "שלושה עשר")
+      , (14, "ארבעה עשר")
+      , (15, "חמישה עשר")
+      , (16, "שישה עשר")
+      , (17, "שבעה עשר")
+      , (18, "שמונה עשר")
+      , (19, "תשעה עשר")
+      , (20, "עשרים")
+      , (21, "עשרים ואחד")
+      , (22, "עשרים ושניים")
+      , (23, "עשרים ושלושה")
+      , (24, "עשרים וארבעה")
+      , (25, "עשרים וחמישה")
+      , (26, "עשרים ושישה")
+      , (27, "עשרים ושבעה")
+      , (28, "עשרים ושמונה")
+      , (29, "עשרים ותשעה")
+      , (30, "שלושים")
+      , (31, "שלושים ואחד")
+      , (32, "שלושים ושניים")
+      , (33, "שלושים ושלושה")
+      , (34, "שלושים וארבעה")
+      , (35, "שלושים וחמישה")
+      , (36, "שלושים ושישה")
+      , (37, "שלושים ושבעה")
+      , (38, "שלושים ושמונה")
+      , (39, "שלושים ותשעה")
+      , (40, "ארבעים")
+      , (41, "ארבעים ואחד")
+      , (42, "ארבעים ושניים")
+      , (43, "ארבעים ושלושה")
+      , (44, "ארבעים וארבעה")
+      , (45, "ארבעים וחמישה")
+      , (46, "ארבעים ושישה")
+      , (47, "ארבעים ושבעה")
+      , (48, "ארבעים ושמונה")
+      , (49, "ארבעים ותשעה")
+      , (50, "חמישים")
+      , (51, "חמישים ואחד")
+      , (52, "חמישים ושניים")
+      , (53, "חמישים ושלושה")
+      , (54, "חמישים וארבעה")
+      , (55, "חמישים וחמישה")
+      , (56, "חמישים ושישה")
+      , (57, "חמישים ושבעה")
+      , (58, "חמישים ושמונה")
+      , (59, "חמישים ותשעה")
+      , (60, "ששים")
+      , (61, "ששים ואחד")
+      , (62, "ששים ושניים")
+      , (63, "ששים ושלושה")
+      , (64, "ששים וארבעה")
+      , (65, "ששים וחמישה")
+      , (66, "ששים ושישה")
+      , (67, "ששים ושבעה")
+      , (68, "ששים ושמונה")
+      , (69, "ששים ותשעה")
+      , (70, "שבעים")
+      , (71, "שבעים ואחד")
+      , (72, "שבעים ושניים")
+      , (73, "שבעים ושלושה")
+      , (74, "שבעים וארבעה")
+      , (75, "שבעים וחמישה")
+      , (76, "שבעים ושישה")
+      , (77, "שבעים ושבעה")
+      , (78, "שבעים ושמונה")
+      , (79, "שבעים ותשעה")
+      , (80, "שמונים")
+      , (81, "שמונים ואחד")
+      , (82, "שמונים ושניים")
+      , (83, "שמונים ושלושה")
+      , (84, "שמונים וארבעה")
+      , (85, "שמונים וחמישה")
+      , (86, "שמונים ושישה")
+      , (87, "שמונים ושבעה")
+      , (88, "שמונים ושמונה")
+      , (89, "שמונים ותשעה")
+      , (90, "תשעים")
+      , (91, "תשעים ואחד")
+      , (92, "תשעים ושניים")
+      , (93, "תשעים ושלושה")
+      , (94, "תשעים וארבעה")
+      , (95, "תשעים וחמישה")
+      , (96, "תשעים ושישה")
+      , (97, "תשעים ושבעה")
+      , (98, "תשעים ושמונה")
+      , (99, "תשעים ותשעה")
+      , (100, "מאה")
+      , (101, "מאה ואחד")
+      , (110, "מאה ועשרה")
+      , (111, "מאה אחד עשרה")
+      , (123, "מאה עשרים ושלושה")
+      , (144, "מאה ארבעים וארבעה")
+      , (199, "מאה תשעים ותשעה")
+      , (200, "מאתיים")
+      , (299, "מאתיים תשעים ותשעה")
+      , (300, "שלוש מאות")
+      , (400, "ארבע מאות")
+      , (900, "תשע מאות")
+      , (1000, "אלף")
+      , (1999, "אלף תשע מאות תשעים ותשעה")
+      , (2000, "אלפיים")
+      , (2999, "אלפיים תשע מאות תשעים ותשעה")
+      , (3000, "שלושת אלפים")
+      , (3110, "שלושת אלפים מאה ועשרה")
+      , (4000, "ארבעת אלפים")
+      , (5000, "חמשת אלפים")
+      , (6000, "ששת אלפים")
+      , (7000, "שבעת אלפים")
+      , (8000, "שמונת אלפים")
+      , (9000, "תשעת אלפים")
+      , (10000, "עשרת אלפים")
+      , (11000, "אחד עשר אלף")
+      , (12000, "שנים עשר אלף")
+      , (dec 5, "מאה אלף")
+      , (dec 6, "מיליון")
+      , (dec 9, "מיליארד")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/HOP/TestData.hs b/src-test/Text/Numeral/Language/HOP/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/HOP/TestData.hs
@@ -0,0 +1,143 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        hop
+
+[@Native name@]     Hopilàvayi
+
+[@English name@]    Hopi
+-}
+
+module Text.Numeral.Language.HOP.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral, (+) )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+-- Sources:
+--   http://www.languagesandnumbers.com/how-to-count-in-hopi/en/hop/
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "suukya’")
+      , (2, "lööyöm")
+      , (3, "pàayom")
+      , (4, "naalöyöm")
+      , (5, "tsivot")
+      , (6, "navay")
+      , (7, "tsange’")
+      , (8, "nanalt")
+      , (9, "pevt")
+      , (10, "pakwt")
+      , (11, "pakwt niikyang suk siikya’ta")
+      , (12, "pakwt niikyang löqmuy siikya’ta")
+      , (13, "pakwt niikyang paykomuy siikya’ta")
+      , (14, "pakwt niikyang naalöqmuy siikya’ta")
+      , (15, "pakwt niikyang tsivot siikya’ta")
+      , (16, "pakwt niikyang navay siikya’ta")
+      , (17, "pakwt niikyang tsange’ siikya’ta")
+      , (18, "pakwt niikyang nanalt siikya’ta")
+      , (19, "pakwt niikyang pevt siikya’ta")
+      , (20, "sunat")
+      , (21, "sunat niikyang suk siikya’ta")
+      , (22, "sunat niikyang löqmuy siikya’ta")
+      , (23, "sunat niikyang paykomuy siikya’ta")
+      , (24, "sunat niikyang naalöqmuy siikya’ta")
+      , (25, "sunat niikyang tsivot siikya’ta")
+      , (26, "sunat niikyang navay siikya’ta")
+      , (27, "sunat niikyang tsange’ siikya’ta")
+      , (28, "sunat niikyang nanalt siikya’ta")
+      , (29, "sunat niikyang pevt siikya’ta")
+      , (30, "payiv pakwt")
+      , (31, "payiv pakwt niikyang suk siikya’ta")
+      , (32, "payiv pakwt niikyang löqmuy siikya’ta")
+      , (33, "payiv pakwt niikyang paykomuy siikya’ta")
+      , (34, "payiv pakwt niikyang naalöqmuy siikya’ta")
+      , (35, "payiv pakwt niikyang tsivot siikya’ta")
+      , (36, "payiv pakwt niikyang navay siikya’ta")
+      , (37, "payiv pakwt niikyang tsange’ siikya’ta")
+      , (38, "payiv pakwt niikyang nanalt siikya’ta")
+      , (39, "payiv pakwt niikyang pevt siikya’ta")
+      , (40, "naalöv pakwt")
+      , (41, "naalöv pakwt niikyang suk siikya’ta")
+      , (42, "naalöv pakwt niikyang löqmuy siikya’ta")
+      , (43, "naalöv pakwt niikyang paykomuy siikya’ta")
+      , (44, "naalöv pakwt niikyang naalöqmuy siikya’ta")
+      , (45, "naalöv pakwt niikyang tsivot siikya’ta")
+      , (46, "naalöv pakwt niikyang navay siikya’ta")
+      , (47, "naalöv pakwt niikyang tsange’ siikya’ta")
+      , (48, "naalöv pakwt niikyang nanalt siikya’ta")
+      , (49, "naalöv pakwt niikyang pevt siikya’ta")
+      , (50, "tsivotsikiv pakwt")
+      , (51, "tsivotsikiv pakwt niikyang suk siikya’ta")
+      , (52, "tsivotsikiv pakwt niikyang löqmuy siikya’ta")
+      , (53, "tsivotsikiv pakwt niikyang paykomuy siikya’ta")
+      , (54, "tsivotsikiv pakwt niikyang naalöqmuy siikya’ta")
+      , (55, "tsivotsikiv pakwt niikyang tsivot siikya’ta")
+      , (56, "tsivotsikiv pakwt niikyang navay siikya’ta")
+      , (57, "tsivotsikiv pakwt niikyang tsange’ siikya’ta")
+      , (58, "tsivotsikiv pakwt niikyang nanalt siikya’ta")
+      , (59, "tsivotsikiv pakwt niikyang pevt siikya’ta")
+      , (60, "navaysikiv pakwt")
+      , (61, "navaysikiv pakwt niikyang suk siikya’ta")
+      , (62, "navaysikiv pakwt niikyang löqmuy siikya’ta")
+      , (63, "navaysikiv pakwt niikyang paykomuy siikya’ta")
+      , (64, "navaysikiv pakwt niikyang naalöqmuy siikya’ta")
+      , (65, "navaysikiv pakwt niikyang tsivot siikya’ta")
+      , (66, "navaysikiv pakwt niikyang navay siikya’ta")
+      , (67, "navaysikiv pakwt niikyang tsange’ siikya’ta")
+      , (68, "navaysikiv pakwt niikyang nanalt siikya’ta")
+      , (69, "navaysikiv pakwt niikyang pevt siikya’ta")
+      , (70, "tsange’sikiv pakwt")
+      , (71, "tsange’sikiv pakwt niikyang suk siikya’ta")
+      , (72, "tsange’sikiv pakwt niikyang löqmuy siikya’ta")
+      , (73, "tsange’sikiv pakwt niikyang paykomuy siikya’ta")
+      , (74, "tsange’sikiv pakwt niikyang naalöqmuy siikya’ta")
+      , (75, "tsange’sikiv pakwt niikyang tsivot siikya’ta")
+      , (76, "tsange’sikiv pakwt niikyang navay siikya’ta")
+      , (77, "tsange’sikiv pakwt niikyang tsange’ siikya’ta")
+      , (78, "tsange’sikiv pakwt niikyang nanalt siikya’ta")
+      , (79, "tsange’sikiv pakwt niikyang pevt siikya’ta")
+      , (80, "nanalsikiv pakwt")
+      , (81, "nanalsikiv pakwt niikyang suk siikya’ta")
+      , (82, "nanalsikiv pakwt niikyang löqmuy siikya’ta")
+      , (83, "nanalsikiv pakwt niikyang paykomuy siikya’ta")
+      , (84, "nanalsikiv pakwt niikyang naalöqmuy siikya’ta")
+      , (85, "nanalsikiv pakwt niikyang tsivot siikya’ta")
+      , (86, "nanalsikiv pakwt niikyang navay siikya’ta")
+      , (87, "nanalsikiv pakwt niikyang tsange’ siikya’ta")
+      , (88, "nanalsikiv pakwt niikyang nanalt siikya’ta")
+      , (89, "nanalsikiv pakwt niikyang pevt siikya’ta")
+      , (90, "peve’sikiv pakwt")
+      , (91, "peve’sikiv pakwt niikyang suk siikya’ta")
+      , (92, "peve’sikiv pakwt niikyang löqmuy siikya’ta")
+      , (93, "peve’sikiv pakwt niikyang paykomuy siikya’ta")
+      , (94, "peve’sikiv pakwt niikyang naalöqmuy siikya’ta")
+      , (95, "peve’sikiv pakwt niikyang tsivot siikya’ta")
+      , (96, "peve’sikiv pakwt niikyang navay siikya’ta")
+      , (97, "peve’sikiv pakwt niikyang tsange’ siikya’ta")
+      , (98, "peve’sikiv pakwt niikyang nanalt siikya’ta")
+      , (99, "peve’sikiv pakwt niikyang pevt siikya’ta")
+      , (100, "palotsikiv pakwt")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/HR/TestData.hs b/src-test/Text/Numeral/Language/HR/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/HR/TestData.hs
@@ -0,0 +1,142 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        hr
+
+[@ISO639-2@]        hrv
+
+[@ISO639-3@]        hrv
+
+[@Native name@]     Hrvatski
+
+[@English name@]    Croatian
+-}
+
+module Text.Numeral.Language.HR.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- HR - Croatian
+--------------------------------------------------------------------------------
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "nula")
+      , (1, "jedan")
+      , (2, "dva")
+      , (3, "tri")
+      , (4, "cetiri")
+      , (5, "pet")
+      , (6, "šest")
+      , (7, "sedam")
+      , (8, "osam")
+      , (9, "devet")
+      , (10, "deset")
+      , (11, "jedanaest")
+      , (12, "dvanaest")
+      , (13, "trinaest")
+      , (14, "cetrnaest")
+      , (15, "petnaest")
+      , (16, "šesnaest")
+      , (17, "sedamnaest")
+      , (18, "osamnaest")
+      , (19, "devetnaest")
+      , (20, "dvadeset")
+      , (21, "dvadeseti jedan")
+      , (22, "dvadeseti dva")
+      , (23, "dvadeseti tri")
+      , (24, "dvadeseti cetiri")
+      , (25, "dvadeseti pet")
+      , (26, "dvadeseti šest")
+      , (27, "dvadeseti sedam")
+      , (28, "dvadeseti osam")
+      , (29, "dvadeseti devet")
+      , (30, "drideset")
+      , (31, "drideseti jedan")
+      , (32, "drideseti dva")
+      , (33, "drideseti tri")
+      , (34, "drideseti cetiri")
+      , (35, "drideseti pet")
+      , (36, "drideseti šest")
+      , (37, "drideseti sedam")
+      , (38, "drideseti osam")
+      , (39, "drideseti devet")
+      , (40, "cetrdeset")
+      , (41, "cetrdeseti jedan")
+      , (42, "cetrdeseti dva")
+      , (43, "cetrdeseti tri")
+      , (44, "cetrdeseti cetiri")
+      , (45, "cetrdeseti pet")
+      , (46, "cetrdeseti šest")
+      , (47, "cetrdeseti sedam")
+      , (48, "cetrdeseti osam")
+      , (49, "cetrdeseti devet")
+      , (50, "pedeset")
+      , (51, "pedeseti jedan")
+      , (52, "pedeseti dva")
+      , (53, "pedeseti tri")
+      , (54, "pedeseti cetiri")
+      , (55, "pedeseti pet")
+      , (56, "pedeseti šest")
+      , (57, "pedeseti sedam")
+      , (58, "pedeseti osam")
+      , (59, "pedeseti devet")
+      , (60, "šezdezet")
+      , (61, "šezdezeti jedan")
+      , (62, "šezdezeti dva")
+      , (63, "šezdezeti tri")
+      , (64, "šezdezeti cetiri")
+      , (65, "šezdezeti pet")
+      , (66, "šezdezeti šest")
+      , (67, "šezdezeti sedam")
+      , (68, "šezdezeti osam")
+      , (69, "šezdezeti devet")
+      , (70, "sedamdezet")
+      , (71, "sedamdezeti jedan")
+      , (72, "sedamdezeti dva")
+      , (73, "sedamdezeti tri")
+      , (74, "sedamdezeti cetiri")
+      , (75, "sedamdezeti pet")
+      , (76, "sedamdezeti šest")
+      , (77, "sedamdezeti sedam")
+      , (78, "sedamdezeti osam")
+      , (79, "sedamdezeti devet")
+      , (80, "osamdeset")
+      , (81, "osamdeseti jedan")
+      , (82, "osamdeseti dva")
+      , (83, "osamdeseti tri")
+      , (84, "osamdeseti cetiri")
+      , (85, "osamdeseti pet")
+      , (86, "osamdeseti šest")
+      , (87, "osamdeseti sedam")
+      , (88, "osamdeseti osam")
+      , (89, "osamdeseti devet")
+      , (90, "deveteset")
+      , (91, "deveteseti jedan")
+      , (92, "deveteseti dva")
+      , (93, "deveteseti tri")
+      , (94, "deveteseti cetiri")
+      , (95, "deveteseti pet")
+      , (96, "deveteseti šest")
+      , (97, "deveteseti sedam")
+      , (98, "deveteseti osam")
+      , (99, "deveteseti devet")
+      , (100, "sto")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/HU/TestData.hs b/src-test/Text/Numeral/Language/HU/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/HU/TestData.hs
@@ -0,0 +1,142 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        hu
+
+[@ISO639-2@]        hun
+
+[@ISO639-3@]        hun
+
+[@Native name@]     magyar
+
+[@English name@]    Hungarian
+-}
+
+module Text.Numeral.Language.HU.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "nulla")
+      , (1, "egy")
+      , (2, "kettö")
+      , (3, "három")
+      , (4, "négy")
+      , (5, "öt")
+      , (6, "hat")
+      , (7, "hét")
+      , (8, "nyolc")
+      , (9, "kilenc")
+      , (10, "tíz")
+      , (11, "tízenegy")
+      , (12, "tízenkettö")
+      , (13, "tízenhárom")
+      , (14, "tízennégy")
+      , (15, "tízenöt")
+      , (16, "tízenhat")
+      , (17, "tízenhét")
+      , (18, "tízennyolc")
+      , (19, "tízenkilenc")
+      , (20, "húsz")
+      , (21, "húszonegy")
+      , (22, "húszonkettö")
+      , (23, "húszonhárom")
+      , (24, "húszonnégy")
+      , (25, "húszonöt")
+      , (26, "húszonhat")
+      , (27, "húszonhét")
+      , (28, "húszonnyolc")
+      , (29, "húszonkilenc")
+      , (30, "harminc")
+      , (31, "harmincegy")
+      , (32, "harminckettö")
+      , (33, "harminchárom")
+      , (34, "harmincnégy")
+      , (35, "harmincöt")
+      , (36, "harminchat")
+      , (37, "harminchét")
+      , (38, "harmincnyolc")
+      , (39, "harminckilenc")
+      , (40, "negyven")
+      , (41, "negyvenegy")
+      , (42, "negyvenkettö")
+      , (43, "negyvenhárom")
+      , (44, "negyvennégy")
+      , (45, "negyvenöt")
+      , (46, "negyvenhat")
+      , (47, "negyvenhét")
+      , (48, "negyvennyolc")
+      , (49, "negyvenkilenc")
+      , (50, "ötven")
+      , (51, "ötvenegy")
+      , (52, "ötvenkettö")
+      , (53, "ötvenhárom")
+      , (54, "ötvennégy")
+      , (55, "ötvenöt")
+      , (56, "ötvenhat")
+      , (57, "ötvenhét")
+      , (58, "ötvennyolc")
+      , (59, "ötvenkilenc")
+      , (60, "hatvan")
+      , (61, "hatvanegy")
+      , (62, "hatvankettö")
+      , (63, "hatvanhárom")
+      , (64, "hatvannégy")
+      , (65, "hatvanöt")
+      , (66, "hatvanhat")
+      , (67, "hatvanhét")
+      , (68, "hatvannyolc")
+      , (69, "hatvankilenc")
+      , (70, "hetven")
+      , (71, "hetvenegy")
+      , (72, "hetvenkettö")
+      , (73, "hetvenhárom")
+      , (74, "hetvennégy")
+      , (75, "hetvenöt")
+      , (76, "hetvenhat")
+      , (77, "hetvenhét")
+      , (78, "hetvennyolc")
+      , (79, "hetvenkilenc")
+      , (80, "nyolcvan")
+      , (81, "nyolcvanegy")
+      , (82, "nyolcvankettö")
+      , (83, "nyolcvanhárom")
+      , (84, "nyolcvannégy")
+      , (85, "nyolcvanöt")
+      , (86, "nyolcvanhat")
+      , (87, "nyolcvanhét")
+      , (88, "nyolcvannyolc")
+      , (89, "nyolcvankilenc")
+      , (90, "kilencven")
+      , (91, "kilencvenegy")
+      , (92, "kilencvenkettö")
+      , (93, "kilencvenhárom")
+      , (94, "kilencvennégy")
+      , (95, "kilencvenöt")
+      , (96, "kilencvenhat")
+      , (97, "kilencvenhét")
+      , (98, "kilencvennyolc")
+      , (99, "kilencvenkilenc")
+      , (100, "száz")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/HY/TestData.hs b/src-test/Text/Numeral/Language/HY/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/HY/TestData.hs
@@ -0,0 +1,208 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        hy
+
+[@ISO639-2B@]       arm
+
+[@ISO639-2T@]       hye
+
+[@ISO639-3@]        hye
+
+[@Native name@]     հայերեն
+
+[@English name@]    Armenian
+-}
+module Text.Numeral.Language.HY.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-armenian/en/hye/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "զրո")
+      , (1, "մեկ")
+      , (2, "երկու")
+      , (3, "երեք")
+      , (4, "չորս")
+      , (5, "հինգ")
+      , (6, "վեց")
+      , (7, "յոթ")
+      , (8, "ութ")
+      , (9, "ինը")
+      , (10, "տաս")
+      , (11, "տասնմեկ")
+      , (12, "տասներկու")
+      , (13, "տասներեք")
+      , (14, "տասնչորս")
+      , (15, "տասնհինգ")
+      , (16, "տասնվեց")
+      , (17, "տասնյոթ")
+      , (18, "տասնութ")
+      , (19, "տասնինը")
+      , (20, "քսան")
+      , (21, "քսան մեկ")
+      , (22, "քսան երկու")
+      , (23, "քսան երեք")
+      , (24, "քսան չորս")
+      , (25, "քսան հինգ")
+      , (26, "քսան վեց")
+      , (27, "քսան յոթ")
+      , (28, "քսան ութ")
+      , (29, "քսան ինը")
+      , (30, "երեսուն")
+      , (31, "երեսուն մեկ")
+      , (32, "երեսուն երկու")
+      , (33, "երեսուն երեք")
+      , (34, "երեսուն չորս")
+      , (35, "երեսուն հինգ")
+      , (36, "երեսուն վեց")
+      , (37, "երեսուն յոթ")
+      , (38, "երեսուն ութ")
+      , (39, "երեսուն ինը")
+      , (40, "քառասուն")
+      , (41, "քառասուն մեկ")
+      , (42, "քառասուն երկու")
+      , (43, "քառասուն երեք")
+      , (44, "քառասուն չորս")
+      , (45, "քառասուն հինգ")
+      , (46, "քառասուն վեց")
+      , (47, "քառասուն յոթ")
+      , (48, "քառասուն ութ")
+      , (49, "քառասուն ինը")
+      , (50, "հիսուն")
+      , (51, "հիսուն մեկ")
+      , (52, "հիսուն երկու")
+      , (53, "հիսուն երեք")
+      , (54, "հիսուն չորս")
+      , (55, "հիսուն հինգ")
+      , (56, "հիսուն վեց")
+      , (57, "հիսուն յոթ")
+      , (58, "հիսուն ութ")
+      , (59, "հիսուն ինը")
+      , (60, "վաթսուն")
+      , (61, "վաթսուն մեկ")
+      , (62, "վաթսուն երկու")
+      , (63, "վաթսուն երեք")
+      , (64, "վաթսուն չորս")
+      , (65, "վաթսուն հինգ")
+      , (66, "վաթսուն վեց")
+      , (67, "վաթսուն յոթ")
+      , (68, "վաթսուն ութ")
+      , (69, "վաթսուն ինը")
+      , (70, "յոթանասուն")
+      , (71, "յոթանասուն մեկ")
+      , (72, "յոթանասուն երկու")
+      , (73, "յոթանասուն երեք")
+      , (74, "յոթանասուն չորս")
+      , (75, "յոթանասուն հինգ")
+      , (76, "յոթանասուն վեց")
+      , (77, "յոթանասուն յոթ")
+      , (78, "յոթանասուն ութ")
+      , (79, "յոթանասուն ինը")
+      , (80, "ութսուն")
+      , (81, "ութսուն մեկ")
+      , (82, "ութսուն երկու")
+      , (83, "ութսուն երեք")
+      , (84, "ութսուն չորս")
+      , (85, "ութսուն հինգ")
+      , (86, "ութսուն վեց")
+      , (87, "ութսուն յոթ")
+      , (88, "ութսուն ութ")
+      , (89, "ութսուն ինը")
+      , (90, "իննսուն")
+      , (91, "իննսուն մեկ")
+      , (92, "իննսուն երկու")
+      , (93, "իննսուն երեք")
+      , (94, "իննսուն չորս")
+      , (95, "իննսուն հինգ")
+      , (96, "իննսուն վեց")
+      , (97, "իննսուն յոթ")
+      , (98, "իննսուն ութ")
+      , (99, "իննսուն ինը")
+      , (100, "հարյուր")
+      , (101, "հարյուր մեկ")
+      , (102, "հարյուր երկու")
+      , (103, "հարյուր երեք")
+      , (104, "հարյուր չորս")
+      , (105, "հարյուր հինգ")
+      , (106, "հարյուր վեց")
+      , (107, "հարյուր յոթ")
+      , (108, "հարյուր ութ")
+      , (109, "հարյուր ինը")
+      , (110, "հարյուր տաս")
+      , (123, "հարյուր քսան երեք")
+      , (200, "երկու հարյուր")
+      , (300, "երեք հարյուր")
+      , (321, "երեք հարյուր քսան մեկ")
+      , (400, "չորս հարյուր")
+      , (500, "հինգ հարյուր")
+      , (600, "վեց հարյուր")
+      , (700, "յոթ հարյուր")
+      , (800, "ութ հարյուր")
+      , (900, "ինը հարյուր")
+      , (909, "ինը հարյուր ինը")
+      , (990, "ինը հարյուր իննսուն")
+      , (999, "ինը հարյուր իննսուն ինը")
+      , (1000, "հազար")
+      , (1001, "հազար մեկ")
+      , (1008, "հազար ութ")
+      , (1234, "հազար երկու հարյուր երեսուն չորս")
+      , (2000, "երկու հազար")
+      , (3000, "երեք հազար")
+      , (4000, "չորս հազար")
+      , (4321, "չորս հազար երեք հարյուր քսան մեկ")
+      , (5000, "հինգ հազար")
+      , (6000, "վեց հազար")
+      , (7000, "յոթ հազար")
+      , (8000, "ութ հազար")
+      , (9000, "ինը հազար")
+      , (10000, "տաս հազար")
+      , (12345, "տասներկու հազար երեք հարյուր քառասուն հինգ")
+      , (20000, "քսան հազար")
+      , (30000, "երեսուն հազար")
+      , (40000, "քառասուն հազար")
+      , (50000, "հիսուն հազար")
+      , (54321, "հիսուն չորս հազար երեք հարյուր քսան մեկ")
+      , (60000, "վաթսուն հազար")
+      , (70000, "յոթանասուն հազար")
+      , (80000, "ութսուն հազար")
+      , (90000, "իննսուն հազար")
+      , (100000, "հարյուր հազար")
+      , (123456, "հարյուր քսան երեք հազար չորս հարյուր հիսուն վեց")
+      , (200000, "երկու հարյուր հազար")
+      , (300000, "երեք հարյուր հազար")
+      , (400000, "չորս հարյուր հազար")
+      , (500000, "հինգ հարյուր հազար")
+      , (600000, "վեց հարյուր հազար")
+      , (654321, "վեց հարյուր հիսուն չորս հազար երեք հարյուր քսան մեկ")
+      , (700000, "յոթ հարյուր հազար")
+      , (800000, "ութ հարյուր հազար")
+      , (900000, "ինը հարյուր հազար")
+      , (1000000, "միլիոն")
+      , (1000000000, "միլիարդ")
+      , (1000000000000, "տրիլիոն")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/IT/TestData.hs b/src-test/Text/Numeral/Language/IT/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/IT/TestData.hs
@@ -0,0 +1,295 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        it
+
+[@ISO639-2B@]       ita
+
+[@ISO639-3@]        ita
+
+[@Native name@]     Italiano
+
+[@English name@]    Italian
+-}
+
+module Text.Numeral.Language.IT.TestData (cardinals, ordinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Grammar
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+-- Sources:
+--   http://www.sf.airnet.ne.jp/~ts/language/number/italian.html
+--   http://www.orbilat.com/Languages/Italian/Grammar/Italian-Numerals.html
+--   http://italian.about.com/library/weekly/aa042600a.htm
+--   http://www.suite101.com/content/how-to-count-in-italian-a146487
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "neuter"
+    , neuter defaultInflection
+    , [ (0, "zero")
+      , (1, "uno")
+      , (2, "due")
+      , (3, "tre")
+      , (4, "quattro")
+      , (5, "cinque")
+      , (6, "sei")
+      , (7, "sette")
+      , (8, "otto")
+      , (9, "nove")
+      , (10, "dieci")
+      , (11, "undici")
+      , (12, "dodici")
+      , (13, "tredici")
+      , (14, "quattordici")
+      , (15, "quindici")
+      , (16, "sedici")
+      , (17, "diciassette")
+      , (18, "diciotto")
+      , (19, "diciannove")
+      , (20, "venti")
+      , (21, "ventuno")
+      , (22, "ventidue")
+      , (23, "ventitré")
+      , (24, "ventiquattro")
+      , (25, "venticinque")
+      , (26, "ventisei")
+      , (27, "ventisette")
+      , (28, "ventotto")
+      , (29, "ventinove")
+      , (30, "trenta")
+      , (31, "trentuno")
+      , (32, "trentadue")
+      , (33, "trentatré")
+      , (34, "trentaquattro")
+      , (35, "trentacinque")
+      , (36, "trentasei")
+      , (37, "trentasette")
+      , (38, "trentotto")
+      , (39, "trentanove")
+      , (40, "quaranta")
+      , (41, "quarantuno")
+      , (42, "quarantadue")
+      , (43, "quarantatré")
+      , (44, "quarantaquattro")
+      , (45, "quarantacinque")
+      , (46, "quarantasei")
+      , (47, "quarantasette")
+      , (48, "quarantotto")
+      , (49, "quarantanove")
+      , (50, "cinquanta")
+      , (51, "cinquantuno")
+      , (52, "cinquantadue")
+      , (53, "cinquantatré")
+      , (54, "cinquantaquattro")
+      , (55, "cinquantacinque")
+      , (56, "cinquantasei")
+      , (57, "cinquantasette")
+      , (58, "cinquantotto")
+      , (59, "cinquantanove")
+      , (60, "sessanta")
+      , (61, "sessantuno")
+      , (62, "sessantadue")
+      , (63, "sessantatré")
+      , (64, "sessantaquattro")
+      , (65, "sessantacinque")
+      , (66, "sessantasei")
+      , (67, "sessantasette")
+      , (68, "sessantotto")
+      , (69, "sessantanove")
+      , (70, "settanta")
+      , (71, "settantuno")
+      , (72, "settantadue")
+      , (73, "settantatré")
+      , (74, "settantaquattro")
+      , (75, "settantacinque")
+      , (76, "settantasei")
+      , (77, "settantasette")
+      , (78, "settantotto")
+      , (79, "settantanove")
+      , (80, "ottanta")
+      , (81, "ottantuno")
+      , (82, "ottantadue")
+      , (83, "ottantatré")
+      , (84, "ottantaquattro")
+      , (85, "ottantacinque")
+      , (86, "ottantasei")
+      , (87, "ottantasette")
+      , (88, "ottantotto")
+      , (89, "ottantanove")
+      , (90, "novanta")
+      , (91, "novantuno")
+      , (92, "novantadue")
+      , (93, "novantatré")
+      , (94, "novantaquattro")
+      , (95, "novantacinque")
+      , (96, "novantasei")
+      , (97, "novantasette")
+      , (98, "novantotto")
+      , (99, "novantanove")
+      , (100, "cento")
+      , (108, "centotto")
+      , (101, "centouno")
+      , (150, "centocinquanta")
+      , (180, "centottanta")
+      , (188, "centottantotto")
+      , (200, "duecento")
+      , (208, "duecentotto")
+      , (280, "duecentottanta")
+      , (288, "duecentottantotto")
+      , (300, "trecento")
+      , (400, "quattrocento")
+      , (456, "quattrocentocinquantasei")
+      , (500, "cinquecento")
+      , (600, "seicento")
+      , (700, "settecento")
+      , (800, "ottocento")
+      , (900, "novecento")
+      , (1000, "mille")
+      , (1001, "milleuno")
+      , (1002, "milledue")
+      , (1100, "millecento")
+      , (1200, "milleduecento")
+      , (2000, "duemila")
+      , (3000, "tremila")
+      , (6827, "seimilaottocentoventisette")
+      , (10000, "diecimila")
+      , (11000, "undicimila")
+      , (100000, "centomila")
+      , (1 ⋅ dec 6, "milione")
+      , (2 ⋅ dec 6, "due milioni")
+      , (125 ⋅ dec 5, "dodici milioni cinquecentomila")
+      , (43152 ⋅ dec 3, "quarantatré milioni centocinquantaduemila")
+      , (132 ⋅ dec 6, "centotrentadue milioni")
+      , (28375 ⋅ dec 4, "duecentottantatré milioni settecentocinquantamila")
+      , (680 ⋅ dec 6, "seicentottanta milioni")
+      , (1 ⋅ dec 9, "miliardo")
+      , (2 ⋅ dec 9, "due miliardi")
+      , (dec 12, "bilione")
+      , (dec 15, "biliardo")
+      , (dec 18, "trilione")
+      , (dec 21, "triliardo")
+      , (dec 24, "quadrilione")
+      , (dec 27, "quadriliardo")
+      , (dec 30, "quintilione")
+      , (dec 33, "quintiliardo")
+      , (dec 36, "sestilione")
+      , (dec 39, "sestiliardo")
+      , (dec 42, "settilione")
+      , (dec 45, "settiliardo")
+      , (dec 48, "ottilione")
+      , (dec 51, "ottiliardo")
+      , (dec 54, "nonilione")
+      , (dec 57, "noniliardo")
+      , (dec 60, "decilione")
+      , (dec 63, "deciliardo")
+      ]
+    )
+  , ( "masculine"
+    , masculine defaultInflection
+    , [ (1, "un")
+      ]
+    )
+  , ( "feminine"
+    , feminine defaultInflection
+    , [ (1, "una")
+      ]
+    )
+  ]
+
+ordinals ∷ (Integral i) ⇒ TestData i
+ordinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "primo")
+      , (2, "secondo")
+      , (3, "terzo")
+      , (4, "quarto")
+      , (5, "quinto")
+      , (6, "sesto")
+      , (7, "settimo")
+      , (8, "ottavo")
+      , (9, "nono")
+      , (10, "decimo")
+      , (11, "undicesimo")
+      , (12, "dodicesimo")
+      , (13, "tredicesimo")
+      , (14, "quattordicesimo")
+      , (15, "quindicesimo")
+      , (16, "sedicesimo")
+      , (17, "diciassettesimo")
+      , (18, "diciottesimo")
+      , (19, "diciannovesimo")
+      , (20, "ventesimo")
+      , (21, "ventunesimo")
+      , (22, "ventiduesimo")
+      , (23, "ventitreesimo")
+      , (24, "ventiquattresimo")
+      , (25, "venticinquesimo")
+      , (26, "ventiseiesimo")
+      , (27, "ventisettesimo")
+      , (28, "ventottesimo")
+      , (29, "ventinovesimo")
+      , (30, "trentesimo")
+      , (31, "trentunesimo")
+      , (32, "trentaduesimo")
+      , (33, "trentatreesimo")
+      , (34, "trentaquattresimo")
+      , (35, "trentacinquesimo")
+      , (36, "trentaseiesimo")
+      , (37, "trentasettesimo")
+      , (38, "trentottesimo")
+      , (39, "trentanovesimo")
+      , (40, "quarantesimo")
+      , (43, "quarantatreesimo")
+      , (50, "cinquantesimo")
+      , (60, "sessantesimo")
+      , (70, "settantesimo")
+      , (80, "ottantesimo")
+      , (89, "ottantanovesimo")
+      , (90, "novantesimo")
+      , (100, "centesimo")
+      , (200, "duecentesimo")
+      , (278, "duecentosettantottesimo")
+      , (300, "trecentesimo")
+      , (400, "quattrocentesimo")
+      , (500, "cinquecentesimo")
+      , (600, "seicentesimo")
+      , (700, "settecentesimo")
+      , (800, "ottocentesimo")
+      , (900, "novecentesimo")
+      , (1000, "millesimo")
+      , (2000, "duemillesimo")
+      , (dec 6, "milionesimo")
+      , (dec 12, "bilionesimo")
+      ]
+    )
+  , ( "feminine"
+    , feminine defaultInflection
+    , [ (1, "prima")
+      , (2, "seconda")
+      , (3, "terza")
+      , (4, "quarta")
+      , (5, "quinta")
+      , (6, "sesta")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/JA/TestData.hs b/src-test/Text/Numeral/Language/JA/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/JA/TestData.hs
@@ -0,0 +1,217 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        ja
+
+[@ISO639-2B@]       jpn
+
+[@ISO639-3@]        jpn
+
+[@Native name@]     日本語
+
+[@English name@]    Japanese
+-}
+
+module Text.Numeral.Language.JA.TestData
+    ( preferred_cardinals
+    , kanji_cardinals
+    , daiji_cardinals
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num, Integral )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- JA
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://en.wikipedia.org/wiki/Japanese_numerals
+  http://www.guidetojapanese.org/numbers.html
+-}
+
+preferred_cardinals ∷ (Num i) ⇒ TestData i
+preferred_cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "rei")
+      , (1, "ichi")
+      , (2, "ni")
+      , (3, "san")
+      , (4, "yon")
+      , (5, "go")
+      , (6, "roku")
+      , (7, "nana")
+      , (8, "hachi")
+      , (9, "kyū")
+      , (10, "jū")
+      , (11, "jū ichi")
+      , (12, "jū ni")
+      , (13, "jū san")
+      , (14, "jū yon")
+      , (15, "jū go")
+      , (16, "jū roku")
+      , (17, "jū nana")
+      , (18, "jū hachi")
+      , (19, "jū kyū")
+      , (20, "nijū")
+      , (21, "nijū ichi")
+      , (22, "nijū ni")
+      , (23, "nijū san")
+      , (24, "nijū yon")
+      , (25, "nijū go")
+      , (26, "nijū roku")
+      , (27, "nijū nana")
+      , (28, "nijū hachi")
+      , (29, "nijū kyū")
+      , (30, "sanjū")
+      , (31, "sanjū ichi")
+      , (32, "sanjū ni")
+      , (33, "sanjū san")
+      , (34, "sanjū yon")
+      , (35, "sanjū go")
+      , (36, "sanjū roku")
+      , (37, "sanjū nana")
+      , (38, "sanjū hachi")
+      , (39, "sanjū kyū")
+      , (40, "yonjū")
+      , (41, "yonjū ichi")
+      , (42, "yonjū ni")
+      , (43, "yonjū san")
+      , (44, "yonjū yon")
+      , (45, "yonjū go")
+      , (46, "yonjū roku")
+      , (47, "yonjū nana")
+      , (48, "yonjū hachi")
+      , (49, "yonjū kyū")
+      , (50, "gojū")
+      , (51, "gojū ichi")
+      , (52, "gojū ni")
+      , (53, "gojū san")
+      , (54, "gojū yon")
+      , (55, "gojū go")
+      , (56, "gojū roku")
+      , (57, "gojū nana")
+      , (58, "gojū hachi")
+      , (59, "gojū kyū")
+      , (60, "rokujū")
+      , (61, "rokujū ichi")
+      , (62, "rokujū ni")
+      , (63, "rokujū san")
+      , (64, "rokujū yon")
+      , (65, "rokujū go")
+      , (66, "rokujū roku")
+      , (67, "rokujū nana")
+      , (68, "rokujū hachi")
+      , (69, "rokujū kyū")
+      , (70, "nanajū")
+      , (71, "nanajū ichi")
+      , (72, "nanajū ni")
+      , (73, "nanajū san")
+      , (74, "nanajū yon")
+      , (75, "nanajū go")
+      , (76, "nanajū roku")
+      , (77, "nanajū nana")
+      , (78, "nanajū hachi")
+      , (79, "nanajū kyū")
+      , (80, "hachijū")
+      , (81, "hachijū ichi")
+      , (82, "hachijū ni")
+      , (83, "hachijū san")
+      , (84, "hachijū yon")
+      , (85, "hachijū go")
+      , (86, "hachijū roku")
+      , (87, "hachijū nana")
+      , (88, "hachijū hachi")
+      , (89, "hachijū kyū")
+      , (90, "kyūjū")
+      , (91, "kyūjū ichi")
+      , (92, "kyūjū ni")
+      , (93, "kyūjū san")
+      , (94, "kyūjū yon")
+      , (95, "kyūjū go")
+      , (96, "kyūjū roku")
+      , (97, "kyūjū nana")
+      , (98, "kyūjū hachi")
+      , (99, "kyūjū kyū")
+      , (100, "hyaku")
+      , (208, "nihyaku hachi")
+      , (280, "nihyaku hachijū")
+      , (2008, "nisen hachi")
+      , (2080, "nisen hachijū")
+      , (2800, "nisen hachihyaku")
+      ]
+    )
+  ]
+
+kanji_cardinals ∷ (Integral i) ⇒ TestData i
+kanji_cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "零")
+      , (1, "一")
+      , (2, "二")
+      , (3, "三")
+      , (4, "四")
+      , (5, "五")
+      , (6, "六")
+      , (7, "七")
+      , (8, "八")
+      , (9, "九")
+      , (10, "十")
+      , (11, "十一")
+      , (12, "十二")
+      , (13, "十三")
+      , (14, "十四")
+      , (21, "二十一")
+      , (28, "二十八")
+      , (100, "百")
+      , (208, "二百八")
+      , (280, "二百八十")
+      , (321, "三百二十一")
+      , (1000, "千")
+      , (2008, "二千八")
+      , (2080, "二千八十")
+      , (2800, "二千八百")
+      , (4321, "四千三百二十一")
+      , (10000, "一万")
+      , (654321, "六十五万四千三百二十一")
+      , (87654321, "八千七百六十五万四千三百二十一")
+      , (100000000, "一億")
+      , (987654321, "九億八千七百六十五万四千三百二十一")
+      , (dec 12, "一兆")
+      ]
+    )
+  ]
+
+daiji_cardinals ∷ (Integral i) ⇒ TestData i
+daiji_cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "零")
+      , (1, "壱")
+      , (2, "弐")
+      , (3, "参")
+      , (4, "四")
+      , (5, "五")
+      , (6, "六")
+      , (7, "七")
+      , (8, "八")
+      , (9, "九")
+      , (10, "拾")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/KAP/TestData.hs b/src-test/Text/Numeral/Language/KAP/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/KAP/TestData.hs
@@ -0,0 +1,169 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        kap
+
+[@Native name@]     бежкьалас миц
+
+[@English name@]    Bezhta
+-}
+module Text.Numeral.Language.KAP.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-bezhta/en/kap/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "nol")
+      , (1, "hõs")
+      , (2, "q’ona")
+      , (3, "łana")
+      , (4, "ṏq’önä")
+      , (5, "łina")
+      , (6, "iłna")
+      , (7, "aƛna")
+      , (8, "beƛna")
+      , (9, "äč’ena")
+      , (10, "ac’ona")
+      , (11, "ac’ona hõs")
+      , (12, "ac’ona q’ona")
+      , (13, "ac’ona łana")
+      , (14, "ac’ona ṏq’önä")
+      , (15, "ac’ona łina")
+      , (16, "ac’ona iłna")
+      , (17, "ac’ona aƛna")
+      , (18, "ac’ona beƛna")
+      , (19, "ac’ona äč’ena")
+      , (20, "qona")
+      , (21, "qona hõs")
+      , (22, "qona q’ona")
+      , (23, "qona łana")
+      , (24, "qona ṏq’önä")
+      , (25, "qona łina")
+      , (26, "qona iłna")
+      , (27, "qona aƛna")
+      , (28, "qona beƛna")
+      , (29, "qona äč’ena")
+      , (30, "łanayig")
+      , (31, "łanayig hõs")
+      , (32, "łanayig q’ona")
+      , (33, "łanayig łana")
+      , (34, "łanayig ṏq’önä")
+      , (35, "łanayig łina")
+      , (36, "łanayig iłna")
+      , (37, "łanayig aƛna")
+      , (38, "łanayig beƛna")
+      , (39, "łanayig äč’ena")
+      , (40, "ṏq’önäyig")
+      , (41, "ṏq’önäyig hõs")
+      , (42, "ṏq’önäyig q’ona")
+      , (43, "ṏq’önäyig łana")
+      , (44, "ṏq’önäyig ṏq’önä")
+      , (45, "ṏq’önäyig łina")
+      , (46, "ṏq’önäyig iłna")
+      , (47, "ṏq’önäyig aƛna")
+      , (48, "ṏq’önäyig beƛna")
+      , (49, "ṏq’önäyig äč’ena")
+      , (50, "łinayig")
+      , (51, "łinayig hõs")
+      , (52, "łinayig q’ona")
+      , (53, "łinayig łana")
+      , (54, "łinayig ṏq’önä")
+      , (55, "łinayig łina")
+      , (56, "łinayig iłna")
+      , (57, "łinayig aƛna")
+      , (58, "łinayig beƛna")
+      , (59, "łinayig äč’ena")
+      , (60, "iłnayig")
+      , (61, "iłnayig hõs")
+      , (62, "iłnayig q’ona")
+      , (63, "iłnayig łana")
+      , (64, "iłnayig ṏq’önä")
+      , (65, "iłnayig łina")
+      , (66, "iłnayig iłna")
+      , (67, "iłnayig aƛna")
+      , (68, "iłnayig beƛna")
+      , (69, "iłnayig äč’ena")
+      , (70, "aƛnayig")
+      , (71, "aƛnayig hõs")
+      , (72, "aƛnayig q’ona")
+      , (73, "aƛnayig łana")
+      , (74, "aƛnayig ṏq’önä")
+      , (75, "aƛnayig łina")
+      , (76, "aƛnayig iłna")
+      , (77, "aƛnayig aƛna")
+      , (78, "aƛnayig beƛna")
+      , (79, "aƛnayig äč’ena")
+      , (80, "beƛnayig")
+      , (81, "beƛnayig hõs")
+      , (82, "beƛnayig q’ona")
+      , (83, "beƛnayig łana")
+      , (84, "beƛnayig ṏq’önä")
+      , (85, "beƛnayig łina")
+      , (86, "beƛnayig iłna")
+      , (87, "beƛnayig aƛna")
+      , (88, "beƛnayig beƛna")
+      , (89, "beƛnayig äč’ena")
+      , (90, "äč’enayig")
+      , (91, "äč’enayig hõs")
+      , (92, "äč’enayig q’ona")
+      , (93, "äč’enayig łana")
+      , (94, "äč’enayig ṏq’önä")
+      , (95, "äč’enayig łina")
+      , (96, "äč’enayig iłna")
+      , (97, "äč’enayig aƛna")
+      , (98, "äč’enayig beƛna")
+      , (99, "äč’enayig äč’ena")
+      , (100, "hõsč’it’")
+      , (101, "hõsč’it’ hõs")
+      , (102, "hõsč’it’ q’ona")
+      , (103, "hõsč’it’ łana")
+      , (104, "hõsč’it’ ṏq’önä")
+      , (105, "hõsč’it’ łina")
+      , (106, "hõsč’it’ iłna")
+      , (107, "hõsč’it’ aƛna")
+      , (108, "hõsč’it’ beƛna")
+      , (109, "hõsč’it’ äč’ena")
+      , (110, "hõsč’it’ ac’ona")
+      , (123, "hõsč’it’ qona łana")
+      , (200, "q’onač’it’")
+      , (300, "łanač’it’")
+      , (321, "łanač’it’ qona hõs")
+      , (400, "ṏq’önäč’it’")
+      , (500, "łinač’it’")
+      , (600, "iłnač’it’")
+      , (700, "aƛnač’it’")
+      , (800, "beƛnač’it’")
+      , (900, "äč’enač’it’")
+      , (909, "äč’enač’it’ äč’ena")
+      , (990, "äč’enač’it’ äč’enayig")
+      , (999, "äč’enač’it’ äč’enayig äč’ena")
+      , (1000, "hazay")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/KEA/TestData.hs b/src-test/Text/Numeral/Language/KEA/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/KEA/TestData.hs
@@ -0,0 +1,207 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        kea
+
+[@Native name@]     Kriolu
+
+[@English name@]    Cape Verdean Creole
+-}
+module Text.Numeral.Language.KEA.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-cape-verdean-creole/en/kea/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "zéru")
+      , (1, "um")
+      , (2, "dós")
+      , (3, "trés")
+      , (4, "kuátu")
+      , (5, "sinku")
+      , (6, "sax")
+      , (7, "séti")
+      , (8, "oitu")
+      , (9, "nóvi")
+      , (10, "dés")
+      , (11, "ónzi")
+      , (12, "duzi")
+      , (13, "treizi")
+      , (14, "katorzi")
+      , (15, "kinzi")
+      , (16, "dizasax")
+      , (17, "dizaséti")
+      , (18, "dizoitu")
+      , (19, "dizanóvi")
+      , (20, "vinti")
+      , (21, "vinti-um")
+      , (22, "vinti-dós")
+      , (23, "vinti-trés")
+      , (24, "vinti-kuátu")
+      , (25, "vinti-sinku")
+      , (26, "vinti-sax")
+      , (27, "vinti-séti")
+      , (28, "vinti-oitu")
+      , (29, "vinti-nóvi")
+      , (30, "trinta")
+      , (31, "trinti-um")
+      , (32, "trinti-dós")
+      , (33, "trinti-trés")
+      , (34, "trinti-kuátu")
+      , (35, "trinti-sinku")
+      , (36, "trinti-sax")
+      , (37, "trinti-séti")
+      , (38, "trinti-oitu")
+      , (39, "trinti-nóvi")
+      , (40, "korénta")
+      , (41, "korénti-um")
+      , (42, "korénti-dós")
+      , (43, "korénti-trés")
+      , (44, "korénti-kuátu")
+      , (45, "korénti-sinku")
+      , (46, "korénti-sax")
+      , (47, "korénti-séti")
+      , (48, "korénti-oitu")
+      , (49, "korénti-nóvi")
+      , (50, "sunkuénta")
+      , (51, "sunkuénti-um")
+      , (52, "sunkuénti-dós")
+      , (53, "sunkuénti-trés")
+      , (54, "sunkuénti-kuátu")
+      , (55, "sunkuénti-sinku")
+      , (56, "sunkuénti-sax")
+      , (57, "sunkuénti-séti")
+      , (58, "sunkuénti-oitu")
+      , (59, "sunkuénti-nóvi")
+      , (60, "sasénta")
+      , (61, "sasénti-um")
+      , (62, "sasénti-dós")
+      , (63, "sasénti-trés")
+      , (64, "sasénti-kuátu")
+      , (65, "sasénti-sinku")
+      , (66, "sasénti-sax")
+      , (67, "sasénti-séti")
+      , (68, "sasénti-oitu")
+      , (69, "sasénti-nóvi")
+      , (70, "saténta")
+      , (71, "saténti-um")
+      , (72, "saténti-dós")
+      , (73, "saténti-trés")
+      , (74, "saténti-kuátu")
+      , (75, "saténti-sinku")
+      , (76, "saténti-sax")
+      , (77, "saténti-séti")
+      , (78, "saténti-oitu")
+      , (79, "saténti-nóvi")
+      , (80, "oiténta")
+      , (81, "oiténti-um")
+      , (82, "oiténti-dós")
+      , (83, "oiténti-trés")
+      , (84, "oiténti-kuátu")
+      , (85, "oiténti-sinku")
+      , (86, "oiténti-sax")
+      , (87, "oiténti-séti")
+      , (88, "oiténti-oitu")
+      , (89, "oiténti-nóvi")
+      , (90, "novénta")
+      , (91, "novénti-um")
+      , (92, "novénti-dós")
+      , (93, "novénti-trés")
+      , (94, "novénti-kuátu")
+      , (95, "novénti-sinku")
+      , (96, "novénti-sax")
+      , (97, "novénti-séti")
+      , (98, "novénti-oitu")
+      , (99, "novénti-nóvi")
+      , (100, "sem")
+      , (101, "senti-um")
+      , (102, "senti-dós")
+      , (103, "senti-trés")
+      , (104, "senti-kuátu")
+      , (105, "senti-sinku")
+      , (106, "senti-sax")
+      , (107, "senti-séti")
+      , (108, "senti-oitu")
+      , (109, "senti-nóvi")
+      , (110, "senti-dés")
+      , (123, "senti-vinti-trés")
+      , (200, "duzéntus")
+      , (300, "trezéntus")
+      , (321, "trezéntus-i-vinti-um")
+      , (400, "kuátuséntus")
+      , (500, "kinhéntus")
+      , (600, "saiséntus")
+      , (700, "sétuséntus")
+      , (800, "oituséntus")
+      , (900, "nóviséntus")
+      , (909, "nóviséntus-i-nóvi")
+      , (990, "nóviséntus-i-novénta")
+      , (999, "nóviséntus-i-novénti-nóvi")
+      , (1000, "mil")
+      , (1001, "um mili--um")
+      , (1008, "um mili--oitu")
+      , (1234, "um mili-duzéntus-i-trinti-kuátu")
+      , (2000, "dós mil")
+      , (3000, "trés mil")
+      , (4000, "kuátu mil")
+      , (4321, "kuátu mili-trezéntus-i-vinti-um")
+      , (5000, "sinku mil")
+      , (6000, "sax mil")
+      , (7000, "séti mil")
+      , (8000, "oitu mil")
+      , (9000, "nóvi mil")
+      , (10000, "dés mil")
+      , (12345, "duzi mili-trezéntus-i-korénti-sinku")
+      , (20000, "vinti mil")
+      , (30000, "trinta mil")
+      , (40000, "korénta mil")
+      , (50000, "sunkuénta mil")
+      , (54321, "sunkuénti-kuátu mili-trezéntus-i-vinti-um")
+      , (60000, "sasénta mil")
+      , (70000, "saténta mil")
+      , (80000, "oiténta mil")
+      , (90000, "novénta mil")
+      , (100000, "um sem mil")
+      , (123456, "senti-vinti-trés mili-kuátuséntus-i-sunkuénti-sax")
+      , (200000, "duzéntus mil")
+      , (300000, "trezéntus mil")
+      , (400000, "kuátuséntus mil")
+      , (500000, "kinhéntus mil")
+      , (600000, "saiséntus mil")
+      , (654321, "saiséntus-i-sunkuénti-kuátu mili-trezéntus-i-vinti-um")
+      , (700000, "sétuséntus mil")
+      , (800000, "oituséntus mil")
+      , (900000, "nóviséntus mil")
+      , (1000000, "um miliom")
+      , (1234567, "um miliom duzéntus-i-trinti-kuátu mili-kinhéntus-i-sasénti-séti")
+      , (7654321, "séti miliom saiséntus-i-sunkuénti-kuátu mili-trezéntus-i-vinti-um")
+      , (1000000000, "um biliom")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/LA/TestData.hs b/src-test/Text/Numeral/Language/LA/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/LA/TestData.hs
@@ -0,0 +1,148 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        la
+
+[@ISO639-2B@]       lat
+
+[@ISO639-3@]        lat
+
+[@Native name@]     Latine
+
+[@English name@]    Latin
+-}
+
+module Text.Numeral.Language.LA.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.informalmusic.com/latinsoc/latnum.html
+  http://www.sf.airnet.ne.jp/~ts/language/number/latin.html
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "nihil")
+      , (1, "ūnus")
+      , (2, "duo")
+      , (3, "trēs")
+      , (4, "quattuor")
+      , (5, "quīnque")
+      , (6, "sex")
+      , (7, "septem")
+      , (8, "octō")
+      , (9, "novem")
+      , (10, "decem")
+      , (11, "ūndecim")
+      , (12, "duodecim")
+      , (13, "trēdecim")
+      , (14, "quattuordecim")
+      , (15, "quīndecim")
+      , (16, "sēdecim")
+      , (17, "septendecim")
+      , (18, "duodēvīgintī")
+      , (19, "ūndēvīgintī")
+      , (20, "vīgintī")
+      , (21, "vīgintī ūnus")
+      , (22, "vīgintī duo")
+      , (23, "vīgintī trēs")
+      , (24, "vīgintī quattuor")
+      , (25, "vīgintī quīnque")
+      , (26, "vīgintī sex")
+      , (27, "vīgintī septem")
+      , (28, "duodētrīgintā")
+      , (29, "ūndētrīgintā")
+      , (30, "trīgintā")
+      , (31, "trīgintā ūnus")
+      , (32, "trīgintā duo")
+      , (33, "trīgintā trēs")
+      , (34, "trīgintā quattuor")
+      , (35, "trīgintā quīnque")
+      , (36, "trīgintā sex")
+      , (37, "trīgintā septem")
+      , (38, "duodēquadrāgintā")
+      , (39, "ūndēquadrāgintā")
+      , (40, "quadrāgintā")
+      , (41, "quadrāgintā ūnus")
+      , (42, "quadrāgintā duo")
+      , (43, "quadrāgintā trēs")
+      , (44, "quadrāgintā quattuor")
+      , (45, "quadrāgintā quīnque")
+      , (46, "quadrāgintā sex")
+      , (47, "quadrāgintā septem")
+      , (48, "duodēquīnquāgintā")
+      , (49, "ūndēquīnquāgintā")
+      , (50, "quīnquāgintā")
+      , (51, "quīnquāgintā ūnus")
+      , (52, "quīnquāgintā duo")
+      , (53, "quīnquāgintā trēs")
+      , (54, "quīnquāgintā quattuor")
+      , (55, "quīnquāgintā quīnque")
+      , (56, "quīnquāgintā sex")
+      , (57, "quīnquāgintā septem")
+      , (58, "duodēsexāgintā")
+      , (59, "ūndēsexāgintā")
+      , (60, "sexāgintā")
+      , (61, "sexāgintā ūnus")
+      , (62, "sexāgintā duo")
+      , (63, "sexāgintā trēs")
+      , (64, "sexāgintā quattuor")
+      , (65, "sexāgintā quīnque")
+      , (66, "sexāgintā sex")
+      , (67, "sexāgintā septem")
+      , (68, "duodēseptuāgintā")
+      , (69, "ūndēseptuāgintā")
+      , (70, "septuāgintā")
+      , (71, "septuāgintā ūnus")
+      , (72, "septuāgintā duo")
+      , (73, "septuāgintā trēs")
+      , (74, "septuāgintā quattuor")
+      , (75, "septuāgintā quīnque")
+      , (76, "septuāgintā sex")
+      , (77, "septuāgintā septem")
+      , (78, "duodēoctōgintā")
+      , (79, "ūndēoctōgintā")
+      , (80, "octōgintā")
+      , (81, "octōgintā ūnus")
+      , (82, "octōgintā duo")
+      , (83, "octōgintā trēs")
+      , (84, "octōgintā quattuor")
+      , (85, "octōgintā quīnque")
+      , (86, "octōgintā sex")
+      , (87, "octōgintā septem")
+      , (88, "duodēnōnāgintā")
+      , (89, "ūndēnōnāgintā")
+      , (90, "nōnāgintā")
+      , (91, "nōnāgintā ūnus")
+      , (92, "nōnāgintā duo")
+      , (93, "nōnāgintā trēs")
+      , (94, "nōnāgintā quattuor")
+      , (95, "nōnāgintā quīnque")
+      , (96, "nōnāgintā sex")
+      , (97, "nōnāgintā septem")
+      , (98, "duodēcentum")
+      , (99, "ūndēcentum")
+      , (100, "centum")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/LLD/TestData.hs b/src-test/Text/Numeral/Language/LLD/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/LLD/TestData.hs
@@ -0,0 +1,155 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        lld
+
+[@Native name@]     Ladin
+
+[@English name@]    Ladin
+-}
+
+module Text.Numeral.Language.LLD.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral, (+) )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Grammar
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+-- Sources:
+--   http://www.languagesandnumbers.com/how-to-count-in-ladin/en/lld/
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "masculine"
+    , masculine defaultInflection
+    , [ (0, "zero")
+      , (1, "un")
+      , (2, "doi")
+      , (3, "trei")
+      , (4, "cater")
+      , (5, "cinch")
+      , (6, "sies")
+      , (7, "set")
+      , (8, "ot")
+      , (9, "nuef")
+      , (10, "diesc")
+      , (11, "undesc")
+      , (12, "dodesc")
+      , (13, "tredesc")
+      , (14, "catordesc")
+      , (15, "chindesc")
+      , (16, "seidesc")
+      , (17, "dejesset")
+      , (18, "dejedot")
+      , (19, "dejenuef")
+      , (20, "vint")
+      , (21, "vintun")
+      , (22, "vintedoi")
+      , (23, "vintetrei")
+      , (24, "vintecater")
+      , (25, "vintecinch")
+      , (26, "vintesies")
+      , (27, "vinteset")
+      , (28, "vintot")
+      , (29, "vintenuef")
+      , (30, "trenta")
+      , (31, "trentun")
+      , (32, "trentedoi")
+      , (33, "trentetrei")
+      , (34, "trentecater")
+      , (35, "trentecinch")
+      , (36, "trentesies")
+      , (37, "trenteset")
+      , (38, "trenteot")
+      , (39, "trentenuef")
+      , (40, "caranta")
+      , (41, "carantun")
+      , (42, "carantedoi")
+      , (43, "carantetrei")
+      , (44, "carantecater")
+      , (45, "carantecinch")
+      , (46, "carantesies")
+      , (47, "caranteset")
+      , (48, "carantot")
+      , (49, "carantenuef")
+      , (50, "cincanta")
+      , (51, "cincantun")
+      , (52, "cincantedoi")
+      , (53, "cincantetrei")
+      , (54, "cincantecater")
+      , (55, "cincantecinch")
+      , (56, "cincantesies")
+      , (57, "cincanteset")
+      , (58, "cincantot")
+      , (59, "cincantenuef")
+      , (60, "sessanta")
+      , (70, "setanta")
+      , (80, "otanta")
+      , (90, "nonanta")
+      , (100, "cent")
+      , (101, "centeun")
+      , (102, "centedoi")
+      , (103, "centetrei")
+      , (200, "doicent")
+      , (300, "treicent")
+      , (400, "catercent")
+      , (401, "catercenteun")
+      , (402, "catercentedoi")
+      , (403, "catercentetrei")
+      , (500, "cinchcent")
+      , (600, "siesçent")
+      , (700, "setcent")
+      , (800, "otcent")
+      , (900, "nuefcent")
+      , (999, "nuefcentenonantenuef")
+      , (1000, "mile")
+      , (1001, "mileun")
+      , (1100, "milecent")
+      , (1110, "milecentediesc")
+      , (1234, "miledoicentetrentecater")
+      , (2000, "doimile")
+      , (3000, "treimile")
+      , (4000, "catermile")
+      , (5000, "cinchmile")
+      , (5678, "cinchmilesiesçentesetantot")
+      , (6000, "siesmile")
+      , (7000, "setmile")
+      , (8000, "otmile")
+      , (9000, "nuefmile")
+      , (12345, "dodescmiletreicentecarantecinch")
+      , (dec 6, "un milion")
+      , (dec 6 + 1, "un milioneun")
+      , (2 ⋅ dec 6, "doi milion")
+      , (123456789, "centevintetrei milionecatercentecincantesiesmilesetcenteotantenuef")
+      , (dec 9, "un miliard")
+      , (2 ⋅ dec 9, "doi miliard")
+      , (9876543210, "nuef miliardeotcentesetantesies milionecinchcentecarantetreimiledoicentediesc")
+      , (9999999999, "nuef miliardenuefcentenonantenuef milionenuefcentenonantenuefmilenuefcentenonantenuef")
+      ]
+    )
+  , ( "feminine"
+    , feminine defaultInflection
+    , [ (1, "una")
+      , (2, "does")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/MG/TestData.hs b/src-test/Text/Numeral/Language/MG/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/MG/TestData.hs
@@ -0,0 +1,162 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        mg
+
+[@ISO639-2@]        mlg
+
+[@ISO639-3@]        mlg
+
+[@Native name@]     -
+
+[@English name@]    Malagasy
+-}
+
+module Text.Numeral.Language.MG.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "numerals" Text.Numeral.Misc ( dec )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://en.wikipedia.org/wiki/Malagasy_language
+  http://www.sf.airnet.ne.jp/~ts/language/number/malagasy.html
+-}
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "haotra")
+      , (1, "iray")
+      , (2, "roa")
+      , (3, "telo")
+      , (4, "efatra")
+      , (5, "dimy")
+      , (6, "enina")
+      , (7, "fito")
+      , (8, "valo")
+      , (9, "sivy")
+      , (10, "folo")
+      , (11, "iraika ambin'ny folo")
+      , (12, "roa ambin'ny folo")
+      , (13, "telo ambin'ny folo")
+      , (14, "efatra ambin'ny folo")
+      , (15, "dimy ambin'ny folo")
+      , (16, "enina ambin'ny folo")
+      , (17, "fito ambin'ny folo")
+      , (18, "valo ambin'ny folo")
+      , (19, "sivy ambin'ny folo")
+      , (20, "roapolo")
+      , (21, "iraika amby roapolo")
+      , (22, "roa amby roapolo")
+      , (23, "telo amby roapolo")
+      , (24, "efatra amby roapolo")
+      , (25, "dimy amby roapolo")
+      , (26, "enina amby roapolo")
+      , (27, "fito amby roapolo")
+      , (28, "valo amby roapolo")
+      , (29, "sivy amby roapolo")
+      , (30, "telopolo")
+      , (31, "iraika amby telopolo")
+      , (32, "roa amby telopolo")
+      , (33, "telo amby telopolo")
+      , (34, "efatra amby telopolo")
+      , (35, "dimy amby telopolo")
+      , (36, "enina amby telopolo")
+      , (37, "fito amby telopolo")
+      , (38, "valo amby telopolo")
+      , (39, "sivy amby telopolo")
+      , (40, "efapolo")
+      , (41, "iraika amby efapolo")
+      , (42, "roa amby efapolo")
+      , (43, "telo amby efapolo")
+      , (44, "efatra amby efapolo")
+      , (45, "dimy amby efapolo")
+      , (46, "enina amby efapolo")
+      , (47, "fito amby efapolo")
+      , (48, "valo amby efapolo")
+      , (49, "sivy amby efapolo")
+      , (50, "dimampolo")
+      , (51, "iraika amby dimampolo")
+      , (52, "roa amby dimampolo")
+      , (53, "telo amby dimampolo")
+      , (54, "efatra amby dimampolo")
+      , (55, "dimy amby dimampolo")
+      , (56, "enina amby dimampolo")
+      , (57, "fito amby dimampolo")
+      , (58, "valo amby dimampolo")
+      , (59, "sivy amby dimampolo")
+      , (60, "enimpolo")
+      , (61, "iraika amby enimpolo")
+      , (62, "roa amby enimpolo")
+      , (63, "telo amby enimpolo")
+      , (64, "efatra amby enimpolo")
+      , (65, "dimy amby enimpolo")
+      , (66, "enina amby enimpolo")
+      , (67, "fito amby enimpolo")
+      , (68, "valo amby enimpolo")
+      , (69, "sivy amby enimpolo")
+      , (70, "fitopolo")
+      , (71, "iraika amby fitopolo")
+      , (72, "roa amby fitopolo")
+      , (73, "telo amby fitopolo")
+      , (74, "efatra amby fitopolo")
+      , (75, "dimy amby fitopolo")
+      , (76, "enina amby fitopolo")
+      , (77, "fito amby fitopolo")
+      , (78, "valo amby fitopolo")
+      , (79, "sivy amby fitopolo")
+      , (80, "valopolo")
+      , (81, "iraika amby valopolo")
+      , (82, "roa amby valopolo")
+      , (83, "telo amby valopolo")
+      , (84, "efatra amby valopolo")
+      , (85, "dimy amby valopolo")
+      , (86, "enina amby valopolo")
+      , (87, "fito amby valopolo")
+      , (88, "valo amby valopolo")
+      , (89, "sivy amby valopolo")
+      , (90, "sivifolo")
+      , (91, "iraika amby sivifolo")
+      , (92, "roa amby sivifolo")
+      , (93, "telo amby sivifolo")
+      , (94, "efatra amby sivifolo")
+      , (95, "dimy amby sivifolo")
+      , (96, "enina amby sivifolo")
+      , (97, "fito amby sivifolo")
+      , (98, "valo amby sivifolo")
+      , (99, "sivy amby sivifolo")
+      , (100, "zato")
+      , (200, "roanjato")
+      , (300, "telonjato")
+      , (400, "efajato")
+      , (500, "dimanjato")
+      , (600, "eninjato")
+      , (700, "fitonjato")
+      , (800, "valonjato")
+      , (900, "sivinjato")
+      , (1000, "arivo")
+      , (dec 4, "alina")
+      , (dec 5, "hetsy")
+      , (123456, "enina amby dimampolo sy efajato sy telo arivo sy roa alina sy hetsy")
+      , (dec 6, "tapitrisa")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/MOH/TestData.hs b/src-test/Text/Numeral/Language/MOH/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/MOH/TestData.hs
@@ -0,0 +1,202 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        moh
+
+[@ISO639-3@]        moh
+
+[@Native name@]     Kanien’kéha
+
+[@English name@]    Mohawk
+-}
+module Text.Numeral.Language.MOH.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-acholi/en/moh
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "énska")
+      , (2, "tékeni")
+      , (3, "áhsen")
+      , (4, "kaié:ri")
+      , (5, "wisk")
+      , (6, "ià:ia’k")
+      , (7, "tsá:ta")
+      , (8, "sha’té:kon")
+      , (9, "tióhton")
+      , (10, "oié:ri")
+      , (11, "énska iawén:re")
+      , (12, "tékeni iawén:re")
+      , (13, "áhsen iawén:re")
+      , (14, "kaié:ri iawén:re")
+      , (15, "wisk iawén:re")
+      , (16, "ià:ia’k iawén:re")
+      , (17, "tsá:ta iawén:re")
+      , (18, "sha’té:kon iawén:re")
+      , (19, "tióhton iawén:re")
+      , (20, "tewáhsen")
+      , (21, "tewáhsen énska")
+      , (22, "tewáhsen tékeni")
+      , (23, "tewáhsen áhsen")
+      , (24, "tewáhsen kaié:ri")
+      , (25, "tewáhsen wisk")
+      , (26, "tewáhsen ià:ia’k")
+      , (27, "tewáhsen tsá:ta")
+      , (28, "tewáhsen sha’té:kon")
+      , (29, "tewáhsen tióhton")
+      , (30, "áhsen niwáhsen")
+      , (31, "áhsen niwáhsen énska")
+      , (32, "áhsen niwáhsen tékeni")
+      , (33, "áhsen niwáhsen áhsen")
+      , (34, "áhsen niwáhsen kaié:ri")
+      , (35, "áhsen niwáhsen wisk")
+      , (36, "áhsen niwáhsen ià:ia’k")
+      , (37, "áhsen niwáhsen tsá:ta")
+      , (38, "áhsen niwáhsen sha’té:kon")
+      , (39, "áhsen niwáhsen tióhton")
+      , (40, "kaié:ri niwáhsen")
+      , (41, "kaié:ri niwáhsen énska")
+      , (42, "kaié:ri niwáhsen tékeni")
+      , (43, "kaié:ri niwáhsen áhsen")
+      , (44, "kaié:ri niwáhsen kaié:ri")
+      , (45, "kaié:ri niwáhsen wisk")
+      , (46, "kaié:ri niwáhsen ià:ia’k")
+      , (47, "kaié:ri niwáhsen tsá:ta")
+      , (48, "kaié:ri niwáhsen sha’té:kon")
+      , (49, "kaié:ri niwáhsen tióhton")
+      , (51, "wisk niwáhsen énska")
+      , (52, "wisk niwáhsen tékeni")
+      , (53, "wisk niwáhsen áhsen")
+      , (54, "wisk niwáhsen kaié:ri")
+      , (55, "wisk niwáhsen wisk")
+      , (56, "wisk niwáhsen ià:ia’k")
+      , (57, "wisk niwáhsen tsá:ta")
+      , (58, "wisk niwáhsen sha’té:kon")
+      , (59, "wisk niwáhsen tióhton")
+      , (60, "iá:ia’k niwáhsen")
+      , (61, "iá:ia’k niwáhsen énska")
+      , (62, "iá:ia’k niwáhsen tékeni")
+      , (63, "iá:ia’k niwáhsen áhsen")
+      , (64, "iá:ia’k niwáhsen kaié:ri")
+      , (65, "iá:ia’k niwáhsen wisk")
+      , (66, "iá:ia’k niwáhsen ià:ia’k")
+      , (67, "iá:ia’k niwáhsen tsá:ta")
+      , (68, "iá:ia’k niwáhsen sha’té:kon")
+      , (69, "iá:ia’k niwáhsen tióhton")
+      , (70, "tsá:ta niwáhsen")
+      , (71, "tsá:ta niwáhsen énska")
+      , (72, "tsá:ta niwáhsen tékeni")
+      , (73, "tsá:ta niwáhsen áhsen")
+      , (74, "tsá:ta niwáhsen kaié:ri")
+      , (75, "tsá:ta niwáhsen wisk")
+      , (76, "tsá:ta niwáhsen ià:ia’k")
+      , (77, "tsá:ta niwáhsen tsá:ta")
+      , (78, "tsá:ta niwáhsen sha’té:kon")
+      , (79, "tsá:ta niwáhsen tióhton")
+      , (80, "sha’té:kon niwáhsen")
+      , (81, "sha’té:kon niwáhsen énska")
+      , (82, "sha’té:kon niwáhsen tékeni")
+      , (83, "sha’té:kon niwáhsen áhsen")
+      , (84, "sha’té:kon niwáhsen kaié:ri")
+      , (85, "sha’té:kon niwáhsen wisk")
+      , (86, "sha’té:kon niwáhsen ià:ia’k")
+      , (87, "sha’té:kon niwáhsen tsá:ta")
+      , (88, "sha’té:kon niwáhsen sha’té:kon")
+      , (89, "sha’té:kon niwáhsen tióhton")
+      , (90, "tióhton niwáhsen")
+      , (91, "tióhton niwáhsen énska")
+      , (92, "tióhton niwáhsen tékeni")
+      , (93, "tióhton niwáhsen áhsen")
+      , (94, "tióhton niwáhsen kaié:ri")
+      , (95, "tióhton niwáhsen wisk")
+      , (96, "tióhton niwáhsen ià:ia’k")
+      , (97, "tióhton niwáhsen tsá:ta")
+      , (98, "tióhton niwáhsen sha’té:kon")
+      , (99, "tióhton niwáhsen tióhton")
+      , (100, "énska tewen’niáwe")
+      , (101, "énska tewen’niáwe tánon énska")
+      , (102, "énska tewen’niáwe tánon tékeni")
+      , (103, "énska tewen’niáwe tánon áhsen")
+      , (104, "énska tewen’niáwe tánon kaié:ri")
+      , (105, "énska tewen’niáwe tánon wisk")
+      , (106, "énska tewen’niáwe tánon ià:ia’k")
+      , (107, "énska tewen’niáwe tánon tsá:ta")
+      , (108, "énska tewen’niáwe tánon sha’té:kon")
+      , (109, "énska tewen’niáwe tánon tióhton")
+      , (110, "énska tewen’niáwe oié:ri")
+      , (123, "énska tewen’niáwe tewáhsen áhsen")
+      , (200, "tékeni tewen’niáwe")
+      , (300, "áhsen tewen’niáwe")
+      , (321, "áhsen tewen’niáwe tewáhsen énska")
+      , (400, "kaié:ri tewen’niáwe")
+      , (500, "wisk tewen’niáwe")
+      , (600, "ià:ia’k tewen’niáwe")
+      , (700, "tsá:ta tewen’niáwe")
+      , (800, "sha’té:kon tewen’niáwe")
+      , (900, "tióhton tewen’niáwe")
+      , (909, "tióhton tewen’niáwe tánon tióhton")
+      , (990, "tióhton tewen’niáwe tióhton niwáhsen")
+      , (999, "tióhton tewen’niáwe tióhton niwáhsen tióhton")
+      , (1000, "oié:ri tewen’niáwe")
+      , (1001, "oié:ri tewen’niáwe tánon énska")
+      , (1008, "oié:ri tewen’niáwe tánon sha’té:kon")
+      , (1234, "oié:ri tewen’niáwe tékeni tewen’niáwe áhsen niwáhsen kaié:ri")
+      , (2000, "tewáhsen tewen’niáwe")
+      , (3000, "áhsen niwáhsen tewen’niáwe")
+      , (4000, "kaié:ri niwáhsen tewen’niáwe")
+      , (4321, "kaié:ri niwáhsen tewen’niáwe áhsen tewen’niáwe tewáhsen énska")
+      , (5000, "wisk niwáhsen tewen’niáwe")
+      , (6000, "iá:ia’k niwáhsen tewen’niáwe")
+      , (7000, "tsá:ta niwáhsen tewen’niáwe")
+      , (8000, "sha’té:kon niwáhsen tewen’niáwe")
+      , (9000, "tióhton niwáhsen tewen’niáwe")
+      , (10000, "oié:ri oié:ri tewen’niáwe")
+      , (12345, "tékeni iawén:re oié:ri tewen’niáwe áhsen tewen’niáwe kaié:ri niwáhsen wisk")
+      , (20000, "tewáhsen niwáhsen tewen’niáwe")
+      , (30000, "áhsen niwáhsen niwáhsen tewen’niáwe")
+      , (40000, "kaié:ri niwáhsen niwáhsen tewen’niáwe")
+      , (50000, "wisk niwáhsen niwáhsen tewen’niáwe")
+      , (54321, "wisk niwáhsen kaié:ri niwáhsen tewen’niáwe áhsen tewen’niáwe tewáhsen énska")
+      , (60000, "iá:ia’k niwáhsen niwáhsen tewen’niáwe")
+      , (70000, "tsá:ta niwáhsen niwáhsen tewen’niáwe")
+      , (80000, "sha’té:kon niwáhsen niwáhsen tewen’niáwe")
+      , (90000, "tióhton niwáhsen niwáhsen tewen’niáwe")
+      , (100000, "énska tewen’niáwe oié:ri tewen’niáwe")
+      , (123456, "énska tewen’niáwe tewáhsen áhsen niwáhsen tewen’niáwe kaié:ri tewen’niáwe wisk niwáhsen ià:ia’k")
+      , (200000, "tékeni tewen’niáwe oié:ri tewen’niáwe")
+      , (300000, "áhsen tewen’niáwe oié:ri tewen’niáwe")
+      , (400000, "kaié:ri tewen’niáwe oié:ri tewen’niáwe")
+      , (500000, "wisk tewen’niáwe oié:ri tewen’niáwe")
+      , (600000, "ià:ia’k tewen’niáwe oié:ri tewen’niáwe")
+      , (654321, "ià:ia’k tewen’niáwe wisk niwáhsen kaié:ri niwáhsen tewen’niáwe áhsen tewen’niáwe tewáhsen énska")
+      , (700000, "tsá:ta tewen’niáwe oié:ri tewen’niáwe")
+      , (800000, "sha’té:kon tewen’niáwe oié:ri tewen’niáwe")
+      , (900000, "tióhton tewen’niáwe oié:ri tewen’niáwe")
+      , (1000000, "énska million")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/NL/TestData.hs b/src-test/Text/Numeral/Language/NL/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/NL/TestData.hs
@@ -0,0 +1,380 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        nl
+
+[@ISO639-2B@]       dut
+
+[@ISO639-3@]        nld
+
+[@Native name@]     Nederlands
+
+[@English name@]    Dutch
+-}
+
+module Text.Numeral.Language.NL.TestData
+    ( cardinals
+    , ordinals
+    , partitives
+    , multiplicatives
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "numerals" Text.Numeral.Grammar
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "singular"
+    , singular defaultInflection
+    , [ (0, "nul")
+      , (1, "één")
+      , (2, "twee")
+      , (3, "drie")
+      , (4, "vier")
+      , (5, "vijf")
+      , (6, "zes")
+      , (7, "zeven")
+      , (8, "acht")
+      , (9, "negen")
+      , (10, "tien")
+      , (11, "elf")
+      , (12, "twaalf")
+      , (13, "dertien")
+      , (14, "veertien")
+      , (15, "vijftien")
+      , (16, "zestien")
+      , (17, "zeventien")
+      , (18, "achtien")
+      , (19, "negentien")
+      , (20, "twintig")
+      , (21, "éénentwintig")
+      , (22, "tweeëntwintig")
+      , (23, "drieëntwintig")
+      , (24, "vierentwintig")
+      , (25, "vijfentwintig")
+      , (26, "zesentwintig")
+      , (27, "zevenentwintig")
+      , (28, "achtentwintig")
+      , (29, "negenentwintig")
+      , (30, "dertig")
+      , (31, "éénendertig")
+      , (32, "tweeëndertig")
+      , (33, "drieëndertig")
+      , (34, "vierendertig")
+      , (35, "vijfendertig")
+      , (36, "zesendertig")
+      , (37, "zevenendertig")
+      , (38, "achtendertig")
+      , (39, "negenendertig")
+      , (40, "veertig")
+      , (41, "éénenveertig")
+      , (42, "tweeënveertig")
+      , (43, "drieënveertig")
+      , (44, "vierenveertig")
+      , (45, "vijfenveertig")
+      , (46, "zesenveertig")
+      , (47, "zevenenveertig")
+      , (48, "achtenveertig")
+      , (49, "negenenveertig")
+      , (50, "vijftig")
+      , (51, "éénenvijftig")
+      , (52, "tweeënvijftig")
+      , (53, "drieënvijftig")
+      , (54, "vierenvijftig")
+      , (55, "vijfenvijftig")
+      , (56, "zesenvijftig")
+      , (57, "zevenenvijftig")
+      , (58, "achtenvijftig")
+      , (59, "negenenvijftig")
+      , (60, "zestig")
+      , (61, "éénenzestig")
+      , (62, "tweeënzestig")
+      , (63, "drieënzestig")
+      , (64, "vierenzestig")
+      , (65, "vijfenzestig")
+      , (66, "zesenzestig")
+      , (67, "zevenenzestig")
+      , (68, "achtenzestig")
+      , (69, "negenenzestig")
+      , (70, "zeventig")
+      , (71, "éénenzeventig")
+      , (72, "tweeënzeventig")
+      , (73, "drieënzeventig")
+      , (74, "vierenzeventig")
+      , (75, "vijfenzeventig")
+      , (76, "zesenzeventig")
+      , (77, "zevenenzeventig")
+      , (78, "achtenzeventig")
+      , (79, "negenenzeventig")
+      , (80, "tachtig")
+      , (81, "éénentachtig")
+      , (82, "tweeëntachtig")
+      , (83, "drieëntachtig")
+      , (84, "vierentachtig")
+      , (85, "vijfentachtig")
+      , (86, "zesentachtig")
+      , (87, "zevenentachtig")
+      , (88, "achtentachtig")
+      , (89, "negenentachtig")
+      , (90, "negentig")
+      , (91, "éénennegentig")
+      , (92, "tweeënnegentig")
+      , (93, "drieënnegentig")
+      , (94, "vierennegentig")
+      , (95, "vijfennegentig")
+      , (96, "zesennegentig")
+      , (97, "zevenennegentig")
+      , (98, "achtennegentig")
+      , (99, "negenennegentig")
+      , (100, "honderd")
+      , (101, "honderdéén")
+      , (108, "honderdacht")
+      , (118, "honderdachtien")
+      , (115, "honderdvijftien")
+      , (500, "vijfhonderd")
+      , (999, "negenhonderdnegenennegentig")
+      , (1000, "duizend")
+      , (1001, "duizendéén")
+      , (1008, "duizendacht")
+      , (8000, "achtduizend")
+      , (900000, "negenhonderdduizend")
+      , (dec 6, "miljoen")
+      , (dec 9, "miljard")
+      , (dec 12, "biljoen")
+      , (dec 15, "biljard")
+      , (dec 18, "triljoen")
+      , (dec 21, "triljard")
+      , (dec 24, "quadriljoen")
+      , (dec 27, "quadriljard")
+      ]
+    )
+  , ( "plural"
+    , plural defaultInflection
+    , [ (1, "éénen")
+      , (2, "tweeën")
+      , (3, "drieën")
+      , (4, "vieren")
+      , (5, "vijven")
+      , (6, "zessen")
+      , (7, "zevens")
+      , (8, "achten")
+      , (9, "negens")
+      , (10, "tienen")
+      , (11, "elven")
+      , (12, "twaalven")
+      , (13, "dertiens")
+      , (14, "veertiens")
+      , (15, "vijftiens")
+      , (16, "zestiens")
+      , (17, "zeventiens")
+      , (18, "achtiens")
+      , (19, "negentiens")
+      , (20, "twintigs")
+      , (100, "honderden")
+      , (1000, "duizenden")
+      , (dec 6, "miljoenen")
+      , (dec 9, "miljarden")
+      , (dec 12, "biljoenen")
+      , (dec 15, "biljarden")
+      ]
+    )
+  , ( "dative"
+    , dative defaultInflection
+    , [ (1, "éénen")
+      , (2, "tweeën")
+      , (3, "drieën")
+      , (4, "vieren")
+      , (5, "vijven")
+      , (6, "zessen")
+      , (7, "zevenen")
+      , (8, "achten")
+      , (9, "negenen")
+      , (10, "tienen")
+      , (11, "elven")
+      , (12, "twaalven")
+      , (13, "dertienen")
+      , (14, "veertienen")
+      , (15, "vijftienen")
+      , (16, "zestienen")
+      , (17, "zeventienen")
+      , (18, "achtienen")
+      , (19, "negentienen")
+      , (20, "twintigen")
+      , (23, "drieëntwintigen")
+      , (100, "honderden")
+      , (1000, "duizenden")
+      , (dec 6, "miljoenen")
+      , (dec 9, "miljarden")
+      , (dec 12, "biljoenen")
+      , (dec 15, "biljarden")
+      ]
+    )
+  ]
+
+ordinals ∷ (Integral i) ⇒ TestData i
+ordinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "eerste")
+      , (2, "tweede")
+      , (3, "derde")
+      , (4, "vierde")
+      , (5, "vijfde")
+      , (6, "zesde")
+      , (7, "zevende")
+      , (8, "achtste")
+      , (9, "negende")
+      , (10, "tiende")
+      , (11, "elfde")
+      , (12, "twaalfde")
+      , (13, "dertiende")
+      , (14, "veertiende")
+      , (15, "vijftiende")
+      , (16, "zestiende")
+      , (17, "zeventiende")
+      , (18, "achtiende")
+      , (19, "negentiende")
+      , (20, "twintigste")
+      , (21, "éénentwintigste")
+      , (22, "tweeëntwintigste")
+      , (23, "drieëntwintigste")
+      , (24, "vierentwintigste")
+      , (25, "vijfentwintigste")
+      , (26, "zesentwintigste")
+      , (27, "zevenentwintigste")
+      , (28, "achtentwintigste")
+      , (29, "negenentwintigste")
+      , (30, "dertigste")
+      , (31, "éénendertigste")
+      , (32, "tweeëndertigste")
+      , (33, "drieëndertigste")
+      , (34, "vierendertigste")
+      , (35, "vijfendertigste")
+      , (36, "zesendertigste")
+      , (37, "zevenendertigste")
+      , (38, "achtendertigste")
+      , (39, "negenendertigste")
+      , (40, "veertigste")
+      , (41, "éénenveertigste")
+      , (42, "tweeënveertigste")
+      , (43, "drieënveertigste")
+      , (44, "vierenveertigste")
+      , (45, "vijfenveertigste")
+      , (46, "zesenveertigste")
+      , (47, "zevenenveertigste")
+      , (48, "achtenveertigste")
+      , (49, "negenenveertigste")
+      , (50, "vijftigste")
+      , (51, "éénenvijftigste")
+      , (52, "tweeënvijftigste")
+      , (53, "drieënvijftigste")
+      , (54, "vierenvijftigste")
+      , (55, "vijfenvijftigste")
+      , (56, "zesenvijftigste")
+      , (57, "zevenenvijftigste")
+      , (58, "achtenvijftigste")
+      , (59, "negenenvijftigste")
+      , (60, "zestigste")
+      , (61, "éénenzestigste")
+      , (62, "tweeënzestigste")
+      , (63, "drieënzestigste")
+      , (64, "vierenzestigste")
+      , (65, "vijfenzestigste")
+      , (66, "zesenzestigste")
+      , (67, "zevenenzestigste")
+      , (68, "achtenzestigste")
+      , (69, "negenenzestigste")
+      , (70, "zeventigste")
+      , (71, "éénenzeventigste")
+      , (72, "tweeënzeventigste")
+      , (73, "drieënzeventigste")
+      , (74, "vierenzeventigste")
+      , (75, "vijfenzeventigste")
+      , (76, "zesenzeventigste")
+      , (77, "zevenenzeventigste")
+      , (78, "achtenzeventigste")
+      , (79, "negenenzeventigste")
+      , (80, "tachtigste")
+      , (81, "éénentachtigste")
+      , (82, "tweeëntachtigste")
+      , (83, "drieëntachtigste")
+      , (84, "vierentachtigste")
+      , (85, "vijfentachtigste")
+      , (86, "zesentachtigste")
+      , (87, "zevenentachtigste")
+      , (88, "achtentachtigste")
+      , (89, "negenentachtigste")
+      , (90, "negentigste")
+      , (91, "éénennegentigste")
+      , (92, "tweeënnegentigste")
+      , (93, "drieënnegentigste")
+      , (94, "vierennegentigste")
+      , (95, "vijfennegentigste")
+      , (96, "zesennegentigste")
+      , (97, "zevenennegentigste")
+      , (98, "achtennegentigste")
+      , (99, "negenennegentigste")
+      , (100, "honderdste")
+      ]
+    )
+  ]
+
+partitives ∷ (Integral i) ⇒ TestData (i, i)
+partitives =
+  [ ("singular", singular defaultInflection, testData)
+  , ("ignored plural", plural defaultInflection, testData)
+  , ("ignored dative", dative defaultInflection, testData)
+  ]
+  where
+    testData =
+      [ ((0, 1), "nul éénde")
+      , ((1, 1), "één éénde")
+      , ((0, 2), "nul tweede")
+      , ((1, 2), "één tweede")  -- optionally "de helft"
+      , ((2, 2), "twee tweede")
+      , ((1, 3), "één derde")
+      , ((2, 3), "twee derde")
+      , ((1, 4), "één vierde")  -- optionally "één kwart"
+      , ((2, 4), "twee vierde") -- optionally "twee kwart"
+      , ((3, 4), "drie vierde") -- optionally "drie kwart"
+      , ((4, 4), "vier vierde") -- optionally "vier kwart"
+      , ((1, 5), "één vijfde")
+      , ((2, 5), "twee vijfde")
+      , ((1, 10), "één tiende")
+      , ((1, 100), "één honderdste")
+      , ((12, 144), "twaalf honderdvierenveertigste")
+      , ((-1, 2), "min één tweede")
+      , ((2, -3), "twee min derde")
+      , ((-3, -5), "min drie min vijfde")
+      ]
+
+multiplicatives ∷ (Integral i) ⇒ TestData i
+multiplicatives =
+  [ ("singular", singular defaultInflection, testData)
+  , ("ignored plural", plural defaultInflection, testData)
+  , ("ignored dative", dative defaultInflection, testData)
+  ]
+  where
+    testData =
+      [ (1, "éénmaal")
+      , (2, "tweemaal")
+      , (3, "driemaal")
+      , (10, "tienmaal")
+      ]
diff --git a/src-test/Text/Numeral/Language/NO/TestData.hs b/src-test/Text/Numeral/Language/NO/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/NO/TestData.hs
@@ -0,0 +1,170 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        nb
+
+[@ISO639-2B@]       nob
+
+[@ISO639-3@]        nob
+
+[@Native name@]     Bokmål
+
+[@English name@]    Norwegian Bokmål
+-}
+
+module Text.Numeral.Language.NO.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+-- Sources:
+--   http://en.wikibooks.org/wiki/Norwegian_Numbers
+--   http://www.sf.airnet.ne.jp/~ts/language/number/norwegian.html
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "null")
+      , (1, "én")
+      , (2, "to")
+      , (3, "tre")
+      , (4, "fire")
+      , (5, "fem")
+      , (6, "seks")
+      , (7, "sju")
+      , (8, "åtte")
+      , (9, "ni")
+      , (10, "ti")
+      , (11, "elleve")
+      , (12, "tolv")
+      , (13, "tretten")
+      , (14, "fjorten")
+      , (15, "femten")
+      , (16, "seksten")
+      , (17, "sytten")
+      , (18, "atten")
+      , (19, "nitten")
+      , (20, "tjue")
+      , (21, "tjueen")
+      , (22, "tjueto")
+      , (23, "tjuetre")
+      , (24, "tjuefire")
+      , (25, "tjuefem")
+      , (26, "tjueseks")
+      , (27, "tjuesju")
+      , (28, "tjueåtte")
+      , (29, "tjueni")
+      , (30, "tretti")
+      , (31, "trettien")
+      , (32, "trettito")
+      , (33, "trettitre")
+      , (34, "trettifire")
+      , (35, "trettifem")
+      , (36, "trettiseks")
+      , (37, "trettisju")
+      , (38, "trettiåtte")
+      , (39, "trettini")
+      , (40, "førti")
+      , (41, "førtien")
+      , (42, "førtito")
+      , (43, "førtitre")
+      , (44, "førtifire")
+      , (45, "førtifem")
+      , (46, "førtiseks")
+      , (47, "førtisju")
+      , (48, "førtiåtte")
+      , (49, "førtini")
+      , (50, "femti")
+      , (51, "femtien")
+      , (52, "femtito")
+      , (53, "femtitre")
+      , (54, "femtifire")
+      , (55, "femtifem")
+      , (56, "femtiseks")
+      , (57, "femtisju")
+      , (58, "femtiåtte")
+      , (59, "femtini")
+      , (60, "seksti")
+      , (61, "sekstien")
+      , (62, "sekstito")
+      , (63, "sekstitre")
+      , (64, "sekstifire")
+      , (65, "sekstifem")
+      , (66, "sekstiseks")
+      , (67, "sekstisju")
+      , (68, "sekstiåtte")
+      , (69, "sekstini")
+      , (70, "sytti")
+      , (71, "syttien")
+      , (72, "syttito")
+      , (73, "syttitre")
+      , (74, "syttifire")
+      , (75, "syttifem")
+      , (76, "syttiseks")
+      , (77, "syttisju")
+      , (78, "syttiåtte")
+      , (79, "syttini")
+      , (80, "åtti")
+      , (81, "åttien")
+      , (82, "åttito")
+      , (83, "åttitre")
+      , (84, "åttifire")
+      , (85, "åttifem")
+      , (86, "åttiseks")
+      , (87, "åttisju")
+      , (88, "åttiåtte")
+      , (89, "åttini")
+      , (90, "nitti")
+      , (91, "nittien")
+      , (92, "nittito")
+      , (93, "nittitre")
+      , (94, "nittifire")
+      , (95, "nittifem")
+      , (96, "nittiseks")
+      , (97, "nittisju")
+      , (98, "nittiåtte")
+      , (99, "nittini")
+      , (100, "hundre")
+      , (123, "hundre tjuetre")
+      , (200, "to hundre")
+      , (300, "tre hundre")
+      , (400, "fire hundre")
+      , (500, "fem hundre")
+      , (600, "seks hundre")
+      , (700, "sju hundre")
+      , (800, "åtte hundre")
+      , (900, "ni hundre")
+      , (1000, "tusen")
+      , (1023, "tusen tjuetre")
+      , (2000, "totusen")
+      , (3000, "tretusen")
+      , (4000, "firetusen")
+      , (5000, "femtusen")
+      , (6000, "sekstusen")
+      , (7000, "sjutusen")
+      , (8000, "åttetusen")
+      , (9000, "nitusen")
+      , (10000, "titusen")
+      , (dec 6, "million")
+      , (2 ⋅ dec 6, "to millioner")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/NQM/TestData.hs b/src-test/Text/Numeral/Language/NQM/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/NQM/TestData.hs
@@ -0,0 +1,141 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2B@]       -
+
+[@ISO639-3@]        nqm
+
+[@Native name@]     -
+
+[@English name@]    Ndom
+-}
+
+module Text.Numeral.Language.NQM.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "sas")
+      , (2, "thef")
+      , (3, "ithin")
+      , (4, "thonith")
+      , (5, "meregh")
+      , (6, "mer")
+      , (7, "mer abo sas")
+      , (8, "mer abo thef")
+      , (9, "mer abo ithin")
+      , (10, "mer abo thonith")
+      , (11, "mer abo meregh")
+      , (12, "mer an thef")
+      , (13, "mer an thef abo sas")
+      , (14, "mer an thef abo thef")
+      , (15, "mer an thef abo ithin")
+      , (16, "mer an thef abo thonith")
+      , (17, "mer an thef abo meregh")
+      , (18, "tondor")
+      , (19, "tondor abo sas")
+      , (20, "tondor abo thef")
+      , (21, "tondor abo ithin")
+      , (22, "tondor abo thonith")
+      , (23, "tondor abo meregh")
+      , (24, "tondor abo mer")
+      , (25, "tondor abo mer abo sas")
+      , (26, "tondor abo mer abo thef")
+      , (27, "tondor abo mer abo ithin")
+      , (28, "tondor abo mer abo thonith")
+      , (29, "tondor abo mer abo meregh")
+      , (30, "tondor abo mer an thef")
+      , (31, "tondor abo mer an thef abo sas")
+      , (32, "tondor abo mer an thef abo thef")
+      , (33, "tondor abo mer an thef abo ithin")
+      , (34, "tondor abo mer an thef abo thonith")
+      , (35, "tondor abo mer an thef abo meregh")
+      , (36, "nif")
+      , (37, "nif abo sas")
+      , (38, "nif abo thef")
+      , (39, "nif abo ithin")
+      , (40, "nif abo thonith")
+      , (41, "nif abo meregh")
+      , (42, "nif abo mer")
+      , (43, "nif abo mer abo sas")
+      , (44, "nif abo mer abo thef")
+      , (45, "nif abo mer abo ithin")
+      , (46, "nif abo mer abo thonith")
+      , (47, "nif abo mer abo meregh")
+      , (48, "nif abo mer an thef")
+      , (49, "nif abo mer an thef abo sas")
+      , (50, "nif abo mer an thef abo thef")
+      , (51, "nif abo mer an thef abo ithin")
+      , (52, "nif abo mer an thef abo thonith")
+      , (53, "nif abo mer an thef abo meregh")
+      , (54, "nif abo tondor")
+      , (55, "nif abo tondor abo sas")
+      , (56, "nif abo tondor abo thef")
+      , (57, "nif abo tondor abo ithin")
+      , (58, "nif abo tondor abo thonith")
+      , (59, "nif abo tondor abo meregh")
+      , (60, "nif abo tondor abo mer")
+      , (61, "nif abo tondor abo mer abo sas")
+      , (62, "nif abo tondor abo mer abo thef")
+      , (63, "nif abo tondor abo mer abo ithin")
+      , (64, "nif abo tondor abo mer abo thonith")
+      , (65, "nif abo tondor abo mer abo meregh")
+      , (66, "nif abo tondor abo mer an thef")
+      , (67, "nif abo tondor abo mer an thef abo sas")
+      , (68, "nif abo tondor abo mer an thef abo thef")
+      , (69, "nif abo tondor abo mer an thef abo ithin")
+      , (70, "nif abo tondor abo mer an thef abo thonith")
+      , (71, "nif abo tondor abo mer an thef abo meregh")
+      , (72, "nif thef")
+      , (73, "nif thef abo sas")
+      , (74, "nif thef abo thef")
+      , (75, "nif thef abo ithin")
+      , (76, "nif thef abo thonith")
+      , (77, "nif thef abo meregh")
+      , (78, "nif thef abo mer")
+      , (79, "nif thef abo mer abo sas")
+      , (80, "nif thef abo mer abo thef")
+      , (81, "nif thef abo mer abo ithin")
+      , (82, "nif thef abo mer abo thonith")
+      , (83, "nif thef abo mer abo meregh")
+      , (84, "nif thef abo mer an thef")
+      , (85, "nif thef abo mer an thef abo sas")
+      , (86, "nif thef abo mer an thef abo thef")
+      , (87, "nif thef abo mer an thef abo ithin")
+      , (88, "nif thef abo mer an thef abo thonith")
+      , (89, "nif thef abo mer an thef abo meregh")
+      , (90, "nif thef abo tondor")
+      , (91, "nif thef abo tondor abo sas")
+      , (92, "nif thef abo tondor abo thef")
+      , (93, "nif thef abo tondor abo ithin")
+      , (94, "nif thef abo tondor abo thonith")
+      , (95, "nif thef abo tondor abo meregh")
+      , (96, "nif thef abo tondor abo mer")
+      , (97, "nif thef abo tondor abo mer abo sas")
+      , (98, "nif thef abo tondor abo mer abo thef")
+      , (99, "nif thef abo tondor abo mer abo ithin")
+      , (100, "nif thef abo tondor abo mer abo thonith")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/OJ/TestData.hs b/src-test/Text/Numeral/Language/OJ/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/OJ/TestData.hs
@@ -0,0 +1,159 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        oj
+
+[@ISO639-2@]        oji
+
+[@ISO639-3@]        oji
+
+[@Native name@]     ᐊᓂᔑᓈᐯᒧᐎᓐ (Anishinaabemowin)
+
+[@English name@]    Ojibwe
+-}
+
+module Text.Numeral.Language.OJ.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.sf.airnet.ne.jp/~ts/language/number/ojibwa.html
+  http://www.languagesandnumbers.com/how-to-count-in-ojibwa/en/oji/
+-}
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "kaagego")
+      , (1, "bezhik")
+      , (2, "niizh")
+      , (3, "nswi")
+      , (4, "niiwin")
+      , (5, "naanan")
+      , (6, "ngodwaaswi")
+      , (7, "niizhwaaswi")
+      , (8, "nshwaaswi")
+      , (9, "zhaangswi")
+      , (10, "mdaaswi")
+      , (11, "mdaaswi shaa bezhik")
+      , (12, "mdaaswi shaa niizh")
+      , (13, "mdaaswi shaa nswi")
+      , (14, "mdaaswi shaa niiwin")
+      , (15, "mdaaswi shaa naanan")
+      , (16, "mdaaswi shaa ngodwaaswi")
+      , (17, "mdaaswi shaa niizhwaaswi")
+      , (18, "mdaaswi shaa nshwaaswi")
+      , (19, "mdaaswi shaa zhaangswi")
+      , (20, "niizhtaana")
+      , (21, "niizhtaana shaa bezhik")
+      , (22, "niizhtaana shaa niizh")
+      , (23, "niizhtaana shaa nswi")
+      , (24, "niizhtaana shaa niiwin")
+      , (25, "niizhtaana shaa naanan")
+      , (26, "niizhtaana shaa ngodwaaswi")
+      , (27, "niizhtaana shaa niizhwaaswi")
+      , (28, "niizhtaana shaa nshwaaswi")
+      , (29, "niizhtaana shaa zhaangswi")
+      , (30, "nsimtaana")
+      , (31, "nsimtaana shaa bezhik")
+      , (32, "nsimtaana shaa niizh")
+      , (33, "nsimtaana shaa nswi")
+      , (34, "nsimtaana shaa niiwin")
+      , (35, "nsimtaana shaa naanan")
+      , (36, "nsimtaana shaa ngodwaaswi")
+      , (37, "nsimtaana shaa niizhwaaswi")
+      , (38, "nsimtaana shaa nshwaaswi")
+      , (39, "nsimtaana shaa zhaangswi")
+      , (40, "niimtaana")
+      , (41, "niimtaana shaa bezhik")
+      , (42, "niimtaana shaa niizh")
+      , (43, "niimtaana shaa nswi")
+      , (44, "niimtaana shaa niiwin")
+      , (45, "niimtaana shaa naanan")
+      , (46, "niimtaana shaa ngodwaaswi")
+      , (47, "niimtaana shaa niizhwaaswi")
+      , (48, "niimtaana shaa nshwaaswi")
+      , (49, "niimtaana shaa zhaangswi")
+      , (50, "naanmitaana")
+      , (51, "naanmitaana shaa bezhik")
+      , (52, "naanmitaana shaa niizh")
+      , (53, "naanmitaana shaa nswi")
+      , (54, "naanmitaana shaa niiwin")
+      , (55, "naanmitaana shaa naanan")
+      , (56, "naanmitaana shaa ngodwaaswi")
+      , (57, "naanmitaana shaa niizhwaaswi")
+      , (58, "naanmitaana shaa nshwaaswi")
+      , (59, "naanmitaana shaa zhaangswi")
+      , (60, "ngodwaasmitaana")
+      , (61, "ngodwaasmitaana shaa bezhik")
+      , (62, "ngodwaasmitaana shaa niizh")
+      , (63, "ngodwaasmitaana shaa nswi")
+      , (64, "ngodwaasmitaana shaa niiwin")
+      , (65, "ngodwaasmitaana shaa naanan")
+      , (66, "ngodwaasmitaana shaa ngodwaaswi")
+      , (67, "ngodwaasmitaana shaa niizhwaaswi")
+      , (68, "ngodwaasmitaana shaa nshwaaswi")
+      , (69, "ngodwaasmitaana shaa zhaangswi")
+      , (70, "niizhwaasmitaana")
+      , (71, "niizhwaasmitaana shaa bezhik")
+      , (72, "niizhwaasmitaana shaa niizh")
+      , (73, "niizhwaasmitaana shaa nswi")
+      , (74, "niizhwaasmitaana shaa niiwin")
+      , (75, "niizhwaasmitaana shaa naanan")
+      , (76, "niizhwaasmitaana shaa ngodwaaswi")
+      , (77, "niizhwaasmitaana shaa niizhwaaswi")
+      , (78, "niizhwaasmitaana shaa nshwaaswi")
+      , (79, "niizhwaasmitaana shaa zhaangswi")
+      , (80, "nshwaasmitaana")
+      , (81, "nshwaasmitaana shaa bezhik")
+      , (82, "nshwaasmitaana shaa niizh")
+      , (83, "nshwaasmitaana shaa nswi")
+      , (84, "nshwaasmitaana shaa niiwin")
+      , (85, "nshwaasmitaana shaa naanan")
+      , (86, "nshwaasmitaana shaa ngodwaaswi")
+      , (87, "nshwaasmitaana shaa niizhwaaswi")
+      , (88, "nshwaasmitaana shaa nshwaaswi")
+      , (89, "nshwaasmitaana shaa zhaangswi")
+      , (90, "zhaangsmitaana")
+      , (91, "zhaangsmitaana shaa bezhik")
+      , (92, "zhaangsmitaana shaa niizh")
+      , (93, "zhaangsmitaana shaa nswi")
+      , (94, "zhaangsmitaana shaa niiwin")
+      , (95, "zhaangsmitaana shaa naanan")
+      , (96, "zhaangsmitaana shaa ngodwaaswi")
+      , (97, "zhaangsmitaana shaa niizhwaaswi")
+      , (98, "zhaangsmitaana shaa nshwaaswi")
+      , (99, "zhaangsmitaana shaa zhaangswi")
+      , (100, "ngodwaak")
+      , (200, "niizhwaak")
+      , (300, "nswaak")
+      , (400, "niiwaak")
+      , (448, "niiwaak shaa niimtaana shaa nshwaaswi")
+      , (500, "naanwaak")
+      , (600, "ngodwaaswaak")
+      , (700, "niizhwaaswaak")
+      , (800, "nshwaaswaak")
+      , (900, "zhaangswaak")
+      , (1000, "mdaaswaak")
+      , (1222, "mdaaswaak shaa niizhwaak shaa niizhtaana shaa niizh")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/PAA/TestData.hs b/src-test/Text/Numeral/Language/PAA/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/PAA/TestData.hs
@@ -0,0 +1,140 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2B@]       paa
+
+[@ISO639-3@]        hui
+
+[@Native name@]     -
+
+[@English name@]    Huli
+-}
+
+module Text.Numeral.Language.PAA.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "mbira")
+      , (2, "kira")
+      , (3, "tebira")
+      , (4, "maria")
+      , (5, "duria")
+      , (6, "waragaria")
+      , (7, "karia")
+      , (8, "halira")
+      , (9, "dira")
+      , (10, "pira")
+      , (11, "bearia")
+      , (12, "hombearia")
+      , (13, "haleria")
+      , (14, "deria")
+      , (15, "nguira")
+      , (16, "nguira-ni mbira")
+      , (17, "nguira-ni kira")
+      , (18, "nguira-ni tebira")
+      , (19, "nguira-ni maria")
+      , (20, "nguira-ni duria")
+      , (21, "nguira-ni waragaria")
+      , (22, "nguira-ni karia")
+      , (23, "nguira-ni halira")
+      , (24, "nguira-ni dira")
+      , (25, "nguira-ni pira")
+      , (26, "nguira-ni bearia")
+      , (27, "nguira-ni hombearia")
+      , (28, "nguira-ni haleria")
+      , (29, "nguira-ni deria")
+      , (30, "ngui ki")
+      , (31, "ngui ki, ngui tebone-gonaga mbira")
+      , (32, "ngui ki, ngui tebone-gonaga kira")
+      , (33, "ngui ki, ngui tebone-gonaga tebira")
+      , (34, "ngui ki, ngui tebone-gonaga maria")
+      , (35, "ngui ki, ngui tebone-gonaga duria")
+      , (36, "ngui ki, ngui tebone-gonaga waragaria")
+      , (37, "ngui ki, ngui tebone-gonaga karia")
+      , (38, "ngui ki, ngui tebone-gonaga halira")
+      , (39, "ngui ki, ngui tebone-gonaga dira")
+      , (40, "ngui ki, ngui tebone-gonaga pira")
+      , (41, "ngui ki, ngui tebone-gonaga bearia")
+      , (42, "ngui ki, ngui tebone-gonaga hombearia")
+      , (43, "ngui ki, ngui tebone-gonaga haleria")
+      , (44, "ngui ki, ngui tebone-gonaga deria")
+      , (45, "ngui tebo")
+      , (46, "ngui tebo, ngui mane-gonaga mbira")
+      , (47, "ngui tebo, ngui mane-gonaga kira")
+      , (48, "ngui tebo, ngui mane-gonaga tebira")
+      , (49, "ngui tebo, ngui mane-gonaga maria")
+      , (50, "ngui tebo, ngui mane-gonaga duria")
+      , (51, "ngui tebo, ngui mane-gonaga waragaria")
+      , (52, "ngui tebo, ngui mane-gonaga karia")
+      , (53, "ngui tebo, ngui mane-gonaga halira")
+      , (54, "ngui tebo, ngui mane-gonaga dira")
+      , (55, "ngui tebo, ngui mane-gonaga pira")
+      , (56, "ngui tebo, ngui mane-gonaga bearia")
+      , (57, "ngui tebo, ngui mane-gonaga hombearia")
+      , (58, "ngui tebo, ngui mane-gonaga haleria")
+      , (59, "ngui tebo, ngui mane-gonaga deria")
+      , (60, "ngui ma")
+      , (61, "ngui ma, ngui dauni-gonaga mbira")
+      , (62, "ngui ma, ngui dauni-gonaga kira")
+      , (63, "ngui ma, ngui dauni-gonaga tebira")
+      , (64, "ngui ma, ngui dauni-gonaga maria")
+      , (65, "ngui ma, ngui dauni-gonaga duria")
+      , (66, "ngui ma, ngui dauni-gonaga waragaria")
+      , (67, "ngui ma, ngui dauni-gonaga karia")
+      , (68, "ngui ma, ngui dauni-gonaga halira")
+      , (69, "ngui ma, ngui dauni-gonaga dira")
+      , (70, "ngui ma, ngui dauni-gonaga pira")
+      , (71, "ngui ma, ngui dauni-gonaga bearia")
+      , (72, "ngui ma, ngui dauni-gonaga hombearia")
+      , (73, "ngui ma, ngui dauni-gonaga haleria")
+      , (74, "ngui ma, ngui dauni-gonaga deria")
+      , (75, "ngui dau")
+      , (76, "ngui dau, ngui waragane-gonaga mbira")
+      , (77, "ngui dau, ngui waragane-gonaga kira")
+      , (78, "ngui dau, ngui waragane-gonaga tebira")
+      , (79, "ngui dau, ngui waragane-gonaga maria")
+      , (80, "ngui dau, ngui waragane-gonaga duria")
+      , (81, "ngui dau, ngui waragane-gonaga waragaria")
+      , (82, "ngui dau, ngui waragane-gonaga karia")
+      , (83, "ngui dau, ngui waragane-gonaga halira")
+      , (84, "ngui dau, ngui waragane-gonaga dira")
+      , (85, "ngui dau, ngui waragane-gonaga pira")
+      , (86, "ngui dau, ngui waragane-gonaga bearia")
+      , (87, "ngui dau, ngui waragane-gonaga hombearia")
+      , (88, "ngui dau, ngui waragane-gonaga haleria")
+      , (89, "ngui dau, ngui waragane-gonaga deria")
+      , (90, "ngui waraga")
+      , (91, "ngui waraga, ngui kane-gonaga mbira")
+      , (92, "ngui waraga, ngui kane-gonaga kira")
+      , (93, "ngui waraga, ngui kane-gonaga tebira")
+      , (94, "ngui waraga, ngui kane-gonaga maria")
+      , (95, "ngui waraga, ngui kane-gonaga duria")
+      , (96, "ngui waraga, ngui kane-gonaga waragaria")
+      , (97, "ngui waraga, ngui kane-gonaga karia")
+      , (98, "ngui waraga, ngui kane-gonaga halira")
+      , (99, "ngui waraga, ngui kane-gonaga dira")
+      , (100, "ngui waraga, ngui kane-gonaga pira")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/PDC/TestData.hs b/src-test/Text/Numeral/Language/PDC/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/PDC/TestData.hs
@@ -0,0 +1,170 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-3@]        pdc
+
+[@Native name@]     Pennsilfaanisch Deitsch
+
+[@English name@]    Pennsylvania German
+-}
+
+module Text.Numeral.Language.PDC.TestData (cardinals) where
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-pennsylvania-german/en/pdc/
+-}
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "null")
+      , (1, "eens")
+      , (2, "zwee")
+      , (3, "drei")
+      , (4, "vier")
+      , (5, "fimf")
+      , (6, "sex")
+      , (7, "siwwe")
+      , (8, "acht")
+      , (9, "nein")
+      , (10, "zehe")
+      , (11, "elf")
+      , (12, "zwelf")
+      , (13, "dreizeh")
+      , (14, "vazeh")
+      , (15, "fuffzeh")
+      , (16, "sechzeh")
+      , (17, "siwwezeh")
+      , (18, "achtzeh")
+      , (19, "neinzeh")
+      , (20, "zwansich")
+      , (21, "eenunzwansich")
+      , (22, "zweeunzwansich")
+      , (23, "dreiunzwansich")
+      , (24, "vierunzwansich")
+      , (25, "fimfunzwansich")
+      , (26, "sexunzwansich")
+      , (27, "siwweunzwansich")
+      , (28, "achtunzwansich")
+      , (29, "neinunzwansich")
+      , (30, "dreissich")
+      , (31, "eenundreissich")
+      , (32, "zweeundreissich")
+      , (33, "dreiundreissich")
+      , (34, "vierundreissich")
+      , (35, "fimfundreissich")
+      , (36, "sexundreissich")
+      , (37, "siwweundreissich")
+      , (38, "achtundreissich")
+      , (39, "neinundreissich")
+      , (40, "vazich")
+      , (41, "eenunvazich")
+      , (42, "zweeunvazich")
+      , (43, "dreiunvazich")
+      , (44, "vierunvazich")
+      , (45, "fimfunvazich")
+      , (46, "sexunvazich")
+      , (47, "siwweunvazich")
+      , (48, "achtunvazich")
+      , (49, "neinunvazich")
+      , (50, "fuffzich")
+      , (51, "eenunfuffzich")
+      , (52, "zweeunfuffzich")
+      , (53, "dreiunfuffzich")
+      , (54, "vierunfuffzich")
+      , (55, "fimfunfuffzich")
+      , (56, "sexunfuffzich")
+      , (57, "siwweunfuffzich")
+      , (58, "achtunfuffzich")
+      , (59, "neinunfuffzich")
+      , (60, "sechzich")
+      , (61, "eenunsechzich")
+      , (62, "zweeunsechzich")
+      , (63, "dreiunsechzich")
+      , (64, "vierunsechzich")
+      , (65, "fimfunsechzich")
+      , (66, "sexunsechzich")
+      , (67, "siwweunsechzich")
+      , (68, "achtunsechzich")
+      , (69, "neinunsechzich")
+      , (70, "siwwezich")
+      , (71, "eenunsiwwezich")
+      , (72, "zweeunsiwwezich")
+      , (73, "dreiunsiwwezich")
+      , (74, "vierunsiwwezich")
+      , (75, "fimfunsiwwezich")
+      , (76, "sexunsiwwezich")
+      , (77, "siwweunsiwwezich")
+      , (78, "achtunsiwwezich")
+      , (79, "neinunsiwwezich")
+      , (80, "achtzich")
+      , (81, "eenunachtzich")
+      , (82, "zweeunachtzich")
+      , (83, "dreiunachtzich")
+      , (84, "vierunachtzich")
+      , (85, "fimfunachtzich")
+      , (86, "sexunachtzich")
+      , (87, "siwweunachtzich")
+      , (88, "achtunachtzich")
+      , (89, "neinunachtzich")
+      , (90, "neinzich")
+      , (91, "eenunneinzich")
+      , (92, "zweeunneinzich")
+      , (93, "dreiunneinzich")
+      , (94, "vierunneinzich")
+      , (95, "fimfunneinzich")
+      , (96, "sexunneinzich")
+      , (97, "siwweunneinzich")
+      , (98, "achtunneinzich")
+      , (99, "neinunneinzich")
+      , (100, "en hunnert")
+      , (101, "en hunnert un eens")
+      , (107, "en hunnert un siwwe")
+      , (199, "en hunnert neinunneinzich")
+      , (200, "zwee hunnert")
+      , (201, "zwee hunnert un eens")
+      , (207, "zwee hunnert un siwwe")
+      , (909, "nein hunnert un nein")
+      , (990, "nein hunnert neinzich")
+      , (999, "nein hunnert neinunneinzich")
+      , (1000, "en dausend")
+      , (1001, "en dausend eens")
+      , (1024, "en dausend vierunzwansich")
+      , (1979, "en dausend nein hunnert neinunsiwwezich")
+      , (2048, "zwee dausend achtunvazich")
+      , (3000, "drei dausend")
+      , (4000, "vier dausend")
+      , (4096, "vier dausend sexunneinzich")
+      , (8192, "acht dausend en hunnert zweeunneinzich")
+      , (16384, "sechzeh dausend drei hunnert vierunachtzich")
+      , (32768, "zweeundreissich dausend siwwe hunnert achtunsechzich")
+      , (65536, "fimfunsechzich dausend fimf hunnert sexundreissich")
+      , (131072, "en hunnert eenundreissich dausend zweeunsiwwezich")
+      , (262144, "zwee hunnert zweeunsechzich dausend en hunnert vierunvazich")
+      , (524288, "fimf hunnert vierunzwansich dausend zwee hunnert achtunachtzich")
+      , (dec 6, "en millyon")
+      , (1048576, "en millyon achtunvazich dausend fimf hunnert sexunsiwwezich")
+      , (5 ⋅ dec 6, "fimf millyon")
+      , (123456789, "en hunnert dreiunzwansich millyon vier hunnert sexunfuffzich dausend siwwe hunnert neinunachtzich")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/PL/TestData.hs b/src-test/Text/Numeral/Language/PL/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/PL/TestData.hs
@@ -0,0 +1,204 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        pl
+
+[@ISO639-2@]        pol
+
+[@ISO639-3@]        pol
+
+[@Native name@]     język polski
+
+[@English name@]    Polish
+-}
+
+module Text.Numeral.Language.PL.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+-- Sources:
+--   Krzysztof Skrzętnicki
+--   http://www.polishforums.com/archives/2009/general-language-17/numbers-polish-language-6722/
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "zero")
+      , (1, "jeden")
+      , (2, "dwa")
+      , (3, "trzy")
+      , (4, "cztery")
+      , (5, "pięć")
+      , (6, "sześć")
+      , (7, "siedem")
+      , (8, "osiem")
+      , (9, "dziewięć")
+      , (10, "dziesięć")
+      , (11, "jedenaście")
+      , (12, "dwanaście")
+      , (13, "trzynaście")
+      , (14, "czternaście")
+      , (15, "piętnaście")
+      , (16, "szesnaście")
+      , (17, "siedemnaście")
+      , (18, "osiemnaście")
+      , (19, "dziewiętnaście")
+      , (20, "dwadzieścia")
+      , (21, "dwadzieścia jeden")
+      , (22, "dwadzieścia dwa")
+      , (23, "dwadzieścia trzy")
+      , (24, "dwadzieścia cztery")
+      , (25, "dwadzieścia pięć")
+      , (26, "dwadzieścia sześć")
+      , (27, "dwadzieścia siedem")
+      , (28, "dwadzieścia osiem")
+      , (29, "dwadzieścia dziewięć")
+      , (30, "trzydzieści")
+      , (31, "trzydzieści jeden")
+      , (32, "trzydzieści dwa")
+      , (33, "trzydzieści trzy")
+      , (34, "trzydzieści cztery")
+      , (35, "trzydzieści pięć")
+      , (36, "trzydzieści sześć")
+      , (37, "trzydzieści siedem")
+      , (38, "trzydzieści osiem")
+      , (39, "trzydzieści dziewięć")
+      , (40, "czterdzieści")
+      , (41, "czterdzieści jeden")
+      , (42, "czterdzieści dwa")
+      , (43, "czterdzieści trzy")
+      , (44, "czterdzieści cztery")
+      , (45, "czterdzieści pięć")
+      , (46, "czterdzieści sześć")
+      , (47, "czterdzieści siedem")
+      , (48, "czterdzieści osiem")
+      , (49, "czterdzieści dziewięć")
+      , (50, "pięćdziesiąt")
+      , (51, "pięćdziesiąt jeden")
+      , (52, "pięćdziesiąt dwa")
+      , (53, "pięćdziesiąt trzy")
+      , (54, "pięćdziesiąt cztery")
+      , (55, "pięćdziesiąt pięć")
+      , (56, "pięćdziesiąt sześć")
+      , (57, "pięćdziesiąt siedem")
+      , (58, "pięćdziesiąt osiem")
+      , (59, "pięćdziesiąt dziewięć")
+      , (60, "sześćdziesiąt")
+      , (61, "sześćdziesiąt jeden")
+      , (62, "sześćdziesiąt dwa")
+      , (63, "sześćdziesiąt trzy")
+      , (64, "sześćdziesiąt cztery")
+      , (65, "sześćdziesiąt pięć")
+      , (66, "sześćdziesiąt sześć")
+      , (67, "sześćdziesiąt siedem")
+      , (68, "sześćdziesiąt osiem")
+      , (69, "sześćdziesiąt dziewięć")
+      , (70, "siedemdziesiąt")
+      , (71, "siedemdziesiąt jeden")
+      , (72, "siedemdziesiąt dwa")
+      , (73, "siedemdziesiąt trzy")
+      , (74, "siedemdziesiąt cztery")
+      , (75, "siedemdziesiąt pięć")
+      , (76, "siedemdziesiąt sześć")
+      , (77, "siedemdziesiąt siedem")
+      , (78, "siedemdziesiąt osiem")
+      , (79, "siedemdziesiąt dziewięć")
+      , (80, "osiemdziesiąt")
+      , (81, "osiemdziesiąt jeden")
+      , (82, "osiemdziesiąt dwa")
+      , (83, "osiemdziesiąt trzy")
+      , (84, "osiemdziesiąt cztery")
+      , (85, "osiemdziesiąt pięć")
+      , (86, "osiemdziesiąt sześć")
+      , (87, "osiemdziesiąt siedem")
+      , (88, "osiemdziesiąt osiem")
+      , (89, "osiemdziesiąt dziewięć")
+      , (90, "dziewięćdziesiąt")
+      , (91, "dziewięćdziesiąt jeden")
+      , (92, "dziewięćdziesiąt dwa")
+      , (93, "dziewięćdziesiąt trzy")
+      , (94, "dziewięćdziesiąt cztery")
+      , (95, "dziewięćdziesiąt pięć")
+      , (96, "dziewięćdziesiąt sześć")
+      , (97, "dziewięćdziesiąt siedem")
+      , (98, "dziewięćdziesiąt osiem")
+      , (99, "dziewięćdziesiąt dziewięć")
+      , (100, "sto")
+      , (101, "sto jeden")
+      , (110, "sto dziesięć")
+      , (111, "sto jedenaście")
+      , (120, "sto dwadzieścia")
+      , (121, "sto dwadzieścia jeden")
+      , (144, "sto czterdzieści cztery")
+      , (200, "dwieście")
+      , (300, "trzysta")
+      , (400, "czterysta")
+      , (500, "pięćset")
+      , (600, "sześćset")
+      , (700, "siedemset")
+      , (777, "siedemset siedemdziesiąt siedem")
+      , (800, "osiemset")
+      , (900, "dziewięćset")
+      , (1000, "tysiąc")
+      , (1001, "tysiąc jeden")
+      , (1010, "tysiąc dziesięć")
+      , (1011, "tysiąc jedenaście")
+      , (1024, "tysiąc dwadzieścia cztery")
+      , (1100, "tysiąc sto")
+      , (1728, "tysiąc siedemset dwadzieścia osiem")
+      , (2000, "dwa tysiące")
+      , (3000, "trzy tysiące")
+      , (4000, "cztery tysiące")
+      , (5000, "pięć tysięcy")
+      , (6000, "sześć tysięcy")
+      , (7000, "siedem tysięcy")
+      , (8000, "osiem tysięcy")
+      , (9000, "dziewięć tysięcy")
+      , (10000, "dziesięć tysięcy")
+      , (100000, "sto tysięcy")
+      , (500000, "pięćset tysięcy")
+      , (1000000, "milion")
+      , (1048576, "milion czterdzieści osiem tysięcy pięćset siedemdziesiąt sześć")
+      , (2 ⋅ dec 6, "dwa miliony")
+      , (3 ⋅ dec 6, "trzy miliony")
+      , (4 ⋅ dec 6, "cztery miliony")
+      , (5 ⋅ dec 6, "pięć milionów")
+      , (6 ⋅ dec 6, "sześć milionów")
+      , (7 ⋅ dec 6, "siedem milionów")
+      , (8 ⋅ dec 6, "osiem milionów")
+      , (9 ⋅ dec 6, "dziewięć milionów")
+      , (dec 7, "dziesięć milionów")
+      , (dec 8, "sto milionów")
+      , (dec 9, "miliard")
+      , (2 ⋅ dec 9, "dwa miliardy")
+      , (3 ⋅ dec 9, "trzy miliardy")
+      , (4 ⋅ dec 9, "cztery miliardy")
+      , (5 ⋅ dec 9, "pięć miliardów")
+      , (6 ⋅ dec 9, "sześć miliardów")
+      , (7 ⋅ dec 9, "siedem miliardów")
+      , (8 ⋅ dec 9, "osiem miliardów")
+      , (9 ⋅ dec 9, "dziewięć miliardów")
+      , (dec 10, "dziesięć miliardów")
+      , (dec 11, "sto miliardów")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/PT/TestData.hs b/src-test/Text/Numeral/Language/PT/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/PT/TestData.hs
@@ -0,0 +1,302 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        pt
+
+[@ISO639-2@]        por
+
+[@ISO639-3@]        por
+
+[@Native name@]     Português
+
+[@English name@]    Portuguese
+-}
+
+module Text.Numeral.Language.PT.TestData (cardinals, ordinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Control.Arrow ( second )
+import "base" Data.List     ( map )
+import "base" Prelude       ( Integral )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Data.Monoid.Unicode   ( (⊕) )
+import "base-unicode-symbols" Prelude.Unicode       ( (⋅) )
+import "numerals" Text.Numeral.Grammar
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+-- Sources:
+--   http://www.sonia-portuguese.com/text/numerals.htm
+--   http://www.smartphrase.com/Portuguese/po_numbers_voc.shtml
+
+base_cardinals ∷ (Integral i) ⇒ [(i, Text)]
+base_cardinals =
+  [ (0, "zero")
+  , (3, "três")
+  , (4, "quatro")
+  , (5, "cinco")
+  , (6, "seis")
+  , (7, "sete")
+  , (8, "oito")
+  , (9, "nove")
+  , (10, "dez")
+  , (11, "onze")
+  , (12, "doze")
+  , (13, "treze")
+  , (14, "catorze")
+  , (15, "quinze")
+  , (16, "dezasseis")
+  , (17, "dezassete")
+  , (18, "dezoito")
+  , (19, "dezanove")
+  , (20, "vinte")
+  , (23, "vinte e três")
+  , (24, "vinte e quatro")
+  , (25, "vinte e cinco")
+  , (26, "vinte e seis")
+  , (27, "vinte e sete")
+  , (28, "vinte e oito")
+  , (29, "vinte e nove")
+  , (30, "trinta")
+  , (33, "trinta e três")
+  , (34, "trinta e quatro")
+  , (35, "trinta e cinco")
+  , (36, "trinta e seis")
+  , (37, "trinta e sete")
+  , (38, "trinta e oito")
+  , (39, "trinta e nove")
+  , (40, "quarenta")
+  , (43, "quarenta e três")
+  , (44, "quarenta e quatro")
+  , (45, "quarenta e cinco")
+  , (46, "quarenta e seis")
+  , (47, "quarenta e sete")
+  , (48, "quarenta e oito")
+  , (49, "quarenta e nove")
+  , (50, "cinquenta")
+  , (53, "cinquenta e três")
+  , (54, "cinquenta e quatro")
+  , (55, "cinquenta e cinco")
+  , (56, "cinquenta e seis")
+  , (57, "cinquenta e sete")
+  , (58, "cinquenta e oito")
+  , (59, "cinquenta e nove")
+  , (60, "sessenta")
+  , (63, "sessenta e três")
+  , (64, "sessenta e quatro")
+  , (65, "sessenta e cinco")
+  , (66, "sessenta e seis")
+  , (67, "sessenta e sete")
+  , (68, "sessenta e oito")
+  , (69, "sessenta e nove")
+  , (70, "setenta")
+  , (73, "setenta e três")
+  , (74, "setenta e quatro")
+  , (75, "setenta e cinco")
+  , (76, "setenta e seis")
+  , (77, "setenta e sete")
+  , (78, "setenta e oito")
+  , (79, "setenta e nove")
+  , (80, "oitenta")
+  , (83, "oitenta e três")
+  , (84, "oitenta e quatro")
+  , (85, "oitenta e cinco")
+  , (86, "oitenta e seis")
+  , (87, "oitenta e sete")
+  , (88, "oitenta e oito")
+  , (89, "oitenta e nove")
+  , (90, "noventa")
+  , (93, "noventa e três")
+  , (94, "noventa e quatro")
+  , (95, "noventa e cinco")
+  , (96, "noventa e seis")
+  , (97, "noventa e sete")
+  , (98, "noventa e oito")
+  , (99, "noventa e nove")
+  , (100, "cem")
+  , (105, "cento e cinco")
+  , (125, "cento e vinte e cinco")
+  , (138, "cento e trinta e oito")
+  , (199, "cento e noventa e nove")
+  , (1000, "mil")
+  , (1008, "mil e oito")
+  , (1985, "mil novecentos e oitenta e cinco")
+  , (3000, "três mil")
+  , (10000, "dez mil")
+  , (100000, "cem mil")
+  , (125000, "cento e vinte e cinco mil")
+  , (735346, "setecentos e trinta e cinco mil trezentos e quarenta e seis")
+  , (dec 6, "um milhão")
+  , (2 ⋅ dec 6, "dois milhões")
+  , (dec 7, "dez milhões")
+  , (dec 9, "um bilhão")
+  , (dec 10, "dez bilhões")
+  , (dec 12, "um trilhão")
+  , (dec 13, "dez trilhões")
+  , (dec 15, "um quatrilhão")
+  , (dec 18, "um quintilhão")
+  , (dec 21, "um sextilhão")
+  , (dec 24, "um septilhão")
+  , (dec 27, "um octilhão")
+  , (dec 30, "um nonilhão")
+  , (dec 33, "um decilhão")
+  , (dec 36, "um undecilhão")
+  , (dec 39, "um duodecilhão")
+  , (dec 42, "um tredecilhão")
+  , (dec 100, "dez duotrigintilhões")
+  ]
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "masculine"
+    , masculine defaultInflection
+    , base_cardinals
+      ⊕ [ (1, "um")
+        , (2, "dois")
+        , (21, "vinte e um")
+        , (22, "vinte e dois")
+        , (31, "trinta e um")
+        , (32, "trinta e dois")
+        , (41, "quarenta e um")
+        , (42, "quarenta e dois")
+        , (51, "cinquenta e um")
+        , (52, "cinquenta e dois")
+        , (61, "sessenta e um")
+        , (62, "sessenta e dois")
+        , (71, "setenta e um")
+        , (72, "setenta e dois")
+        , (81, "oitenta e um")
+        , (82, "oitenta e dois")
+        , (91, "noventa e um")
+        , (92, "noventa e dois")
+        , (101, "cento e um")
+        , (200, "duzentos")
+        , (234, "duzentos e trinta e quatro")
+        , (250, "duzentos e cinquenta")
+        , (300, "trezentos")
+        , (330, "trezentos e trinta")
+        , (375, "trezentos e setenta e cinco")
+        , (400, "quatrocentos")
+        , (467, "quatrocentos e sessenta e sete")
+        , (500, "quinhentos")
+        , (600, "seiscentos")
+        , (700, "setecentos")
+        , (800, "oitocentos")
+        , (900, "novecentos")
+        , (2000, "dois mil")
+        , (200000, "duzentos mil")
+        , (500000, "quinhentos mil")
+        , (100001, "cem mil e um")
+        , (101000, "cento e um mil")
+        , (1537469, "um milhão quinhentos e trinta e sete mil quatrocentos e sessenta e nove")
+        ]
+    )
+  , ( "feminine"
+    , feminine defaultInflection
+    , base_cardinals
+      ⊕ [ (1, "uma")
+        , (2, "duas")
+        , (21, "vinte e uma")
+        , (22, "vinte e duas")
+        , (31, "trinta e uma")
+        , (32, "trinta e duas")
+        , (41, "quarenta e uma")
+        , (42, "quarenta e duas")
+        , (51, "cinquenta e uma")
+        , (52, "cinquenta e duas")
+        , (61, "sessenta e uma")
+        , (62, "sessenta e duas")
+        , (71, "setenta e uma")
+        , (72, "setenta e duas")
+        , (81, "oitenta e uma")
+        , (82, "oitenta e duas")
+        , (91, "noventa e uma")
+        , (92, "noventa e duas")
+        , (101, "cento e uma")
+        , (200, "duzentas")
+        , (234, "duzentas e trinta e quatro")
+        , (250, "duzentas e cinquenta")
+        , (300, "trezentas")
+        , (330, "trezentas e trinta")
+        , (375, "trezentas e setenta e cinco")
+        , (400, "quatrocentas")
+        , (467, "quatrocentas e sessenta e sete")
+        , (500, "quinhentas")
+        , (600, "seiscentas")
+        , (700, "setecentas")
+        , (800, "oitocentas")
+        , (900, "novecentas")
+        , (2000, "duas mil")
+        , (200000, "duzentas mil")
+        , (500000, "quinhentas mil")
+        , (100001, "cem mil e uma")
+        , (101000, "cento e uma mil")
+        , (1537469, "um milhão quinhentas e trinta e sete mil quatrocentas e sessenta e nove")
+        ]
+    )
+  ]
+
+-- These are the base forms of the ordinals, stripped of their
+-- ending. Append "o", "os", "a" or "as" to form combinations of
+-- masculine, feminine, singular and plural ordinals.
+base_ordinals ∷ (Integral i) ⇒ [(i, Text)]
+base_ordinals =
+  [ (1, "primeir")
+  , (2, "segund")
+  , (3, "terceir")
+  , (4, "quart")
+  , (5, "quint")
+  , (6, "sext")
+  , (7, "sétim")
+  , (8, "oitav")
+  , (9, "non")
+  , (10, "décim")
+  , (11, "décimo primeir")
+  , (12, "décimo segund")
+  , (13, "décimo terceir")
+  , (20, "vigésim")
+  , (21, "vigésimo primeir")
+  , (30, "trigésim")
+  , (40, "quadragésim")
+  , (50, "qüinquagésim")
+  , (60, "sexagésim")
+  , (70, "septuagésim")
+  , (80, "octogésim")
+  , (90, "nonagésim")
+  , (100, "centésim")
+  , (200, "ducentésim")
+  , (300, "trecentésim")
+  , (400, "quadringentésim")
+  , (500, "qüingentésim")
+  , (600, "sexcentésim")
+  , (700, "setingentésim")
+  , (800, "octingentésim")
+  , (900, "nongentésim")
+  , (1000, "milésim")
+  ]
+
+ordinals ∷ (Integral i) ⇒ TestData i
+ordinals = map (\(n, f, e) → ( n
+                             , f defaultInflection
+                             , map (second (⊕ e)) base_ordinals)
+                             )
+               [ ("masculine singular", masculine ∘ singular, "o")
+               , ("masculine plural",   masculine ∘ plural,   "os")
+               , ("feminine singular",  feminine  ∘ singular, "a")
+               , ("feminine plural",    feminine  ∘ plural,   "as")
+               ]
diff --git a/src-test/Text/Numeral/Language/RMN_DZA/TestData.hs b/src-test/Text/Numeral/Language/RMN_DZA/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/RMN_DZA/TestData.hs
@@ -0,0 +1,204 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        rmn
+
+[@Native name@]     -
+
+[@English name@]    Balkan Romani
+-}
+module Text.Numeral.Language.RMN_DZA.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-dzambazi-romani/en/rmn-dza/
+-}
+
+-- Note: This is the Prilep dialect as spoken in Macedonia.
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "jekh")
+      , (2, "duj")
+      , (3, "trin")
+      , (4, "štar")
+      , (5, "pandž")
+      , (6, "šov")
+      , (7, "efta")
+      , (8, "oxto")
+      , (9, "iňa")
+      , (10, "deš")
+      , (11, "dešujekh")
+      , (12, "dešuduj")
+      , (13, "dešutrin")
+      , (14, "dešuštar")
+      , (15, "dešupandž")
+      , (16, "dešušov")
+      , (17, "dešuefta")
+      , (18, "dešuoxto")
+      , (19, "dešuiňa")
+      , (20, "biš")
+      , (21, "bišthajekh")
+      , (22, "bišthaduj")
+      , (23, "bišthatrin")
+      , (24, "bišthaštar")
+      , (25, "bišthapandž")
+      , (26, "bišthašov")
+      , (27, "bišthajefta")
+      , (28, "bišthajoxto")
+      , (29, "bišthaiňa")
+      , (30, "tranda")
+      , (31, "trandathajekh")
+      , (32, "trandathaduj")
+      , (33, "trandathatrin")
+      , (34, "trandathaštar")
+      , (35, "trandathapandž")
+      , (36, "trandathašov")
+      , (37, "trandathajefta")
+      , (38, "trandathajoxto")
+      , (39, "trandathajiňa")
+      , (40, "saranda")
+      , (41, "sarandathajekh")
+      , (42, "sarandathaduj")
+      , (43, "sarandathatrin")
+      , (44, "sarandathaštar")
+      , (45, "sarandathapandž")
+      , (46, "sarandathašov")
+      , (47, "sarandathajefta")
+      , (48, "sarandathajoxto")
+      , (49, "sarandathajiňa")
+      , (50, "pinda")
+      , (51, "pindathajekh")
+      , (52, "pindathaduj")
+      , (53, "pindathatrin")
+      , (54, "pindathaštar")
+      , (55, "pindathapandž")
+      , (56, "pindathašov")
+      , (57, "pindathajefta")
+      , (58, "pindathajoxto")
+      , (59, "pindathajiňa")
+      , (60, "šovardeš")
+      , (61, "šovardešthajekh")
+      , (62, "šovardešthaduj")
+      , (63, "šovardešthatrin")
+      , (64, "šovardešthaštar")
+      , (65, "šovardešthapandž")
+      , (66, "šovardešthašov")
+      , (67, "šovardešthajefta")
+      , (68, "šovardešthajoxto")
+      , (69, "šovardešthajiňa")
+      , (70, "eftavardeš")
+      , (71, "eftavardešthajekh")
+      , (72, "eftavardešthaduj")
+      , (73, "eftavardešthatrin")
+      , (74, "eftavardešthaštar")
+      , (75, "eftavardešthapandž")
+      , (76, "eftavardešthašov")
+      , (77, "eftavardešthajefta")
+      , (78, "eftavardešthajoxto")
+      , (79, "eftavardešthajiňa")
+      , (80, "oxtovardeš")
+      , (81, "oxtovardešthajekh")
+      , (82, "oxtovardešthaduj")
+      , (83, "oxtovardešthatrin")
+      , (84, "oxtovardešthaštar")
+      , (85, "oxtovardešthapandž")
+      , (86, "oxtovardešthašov")
+      , (87, "oxtovardešthajefta")
+      , (88, "oxtovardešthajoxto")
+      , (89, "oxtovardešthajiňa")
+      , (90, "iňavardeš")
+      , (91, "iňavardešthajekh")
+      , (92, "iňavardešthaduj")
+      , (93, "iňavardešthatrin")
+      , (94, "iňavardešthaštar")
+      , (95, "iňavardešthapandž")
+      , (96, "iňavardešthašov")
+      , (97, "iňavardešthajefta")
+      , (98, "iňavardešthajoxto")
+      , (99, "iňavardešthajiňa")
+      , (100, "šel")
+      , (101, "šel jekh")
+      , (102, "šel duj")
+      , (103, "šel trin")
+      , (104, "šel štar")
+      , (105, "šel pandž")
+      , (106, "šel šov")
+      , (107, "šel efta")
+      , (108, "šel oxto")
+      , (109, "šel iňa")
+      , (110, "šel deš")
+      , (123, "šel bišthatrin")
+      , (200, "duj šel")
+      , (300, "trin šel")
+      , (321, "trin šel bišthajekh")
+      , (400, "štar šel")
+      , (500, "panšel")
+      , (600, "šov šel")
+      , (700, "efta šel")
+      , (800, "oxto šel")
+      , (900, "iňa šel")
+      , (909, "iňa šel iňa")
+      , (990, "iňa šel iňavardeš")
+      , (999, "iňa šel iňavardešthajiňa")
+      , (1000, "miľa")
+      , (1001, "miľa jekh")
+      , (1008, "miľa oxto")
+      , (1234, "miľa duj šel trandathaštar")
+      , (2000, "duj miľe")
+      , (3000, "trin miľe")
+      , (4000, "štar miľe")
+      , (4321, "štar miľe trin šel bišthajekh")
+      , (5000, "pandž miľe")
+      , (6000, "šov miľe")
+      , (7000, "efta miľe")
+      , (8000, "oxto miľe")
+      , (9000, "iňa miľe")
+      , (10000, "deš miľe")
+      , (12345, "dešuduj miľe trin šel sarandathapandž")
+      , (20000, "biš miľe")
+      , (30000, "tranda miľe")
+      , (40000, "saranda miľe")
+      , (50000, "pinda miľe")
+      , (54321, "pindathaštar miľe trin šel bišthajekh")
+      , (60000, "šovardeš miľe")
+      , (70000, "eftavardeš miľe")
+      , (80000, "oxtovardeš miľe")
+      , (90000, "iňavardeš miľe")
+      , (100000, "šel miľe")
+      , (123456, "šel bišthatrin miľe štar šel pindathašov")
+      , (200000, "duj šel miľe")
+      , (300000, "trin šel miľe")
+      , (400000, "štar šel miľe")
+      , (500000, "panšel miľe")
+      , (600000, "šov šel miľe")
+      , (654321, "šov šel pindathaštar miľe trin šel bišthajekh")
+      , (700000, "efta šel miľe")
+      , (800000, "oxto šel miľe")
+      , (900000, "iňa šel miľe")
+      , (1000000, "milioni")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/RO/TestData.hs b/src-test/Text/Numeral/Language/RO/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/RO/TestData.hs
@@ -0,0 +1,144 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        ro
+
+[@ISO639-2B@]       rum
+
+[@ISO639-2T@]       ron
+
+[@ISO639-3@]        ron
+
+[@Native name@]     română
+
+[@English name@]    Romanian
+-}
+
+module Text.Numeral.Language.RO.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "zero")
+      , (1, "unu")
+      , (2, "doi")
+      , (3, "trei")
+      , (4, "patru")
+      , (5, "cinci")
+      , (6, "sase")
+      , (7, "sapte")
+      , (8, "opt")
+      , (9, "noua")
+      , (10, "zece")
+      , (11, "unsprezece")
+      , (12, "doisprezece")
+      , (13, "treisprezece")
+      , (14, "paisprezece")
+      , (15, "cincisprezece")
+      , (16, "saisprezece")
+      , (17, "saptesprezece")
+      , (18, "optsprezece")
+      , (19, "nouasprezece")
+      , (20, "douazeci")
+      , (21, "douazecisiunu")
+      , (22, "douazecisidoi")
+      , (23, "douazecisitrei")
+      , (24, "douazecisipatru")
+      , (25, "douazecisicinci")
+      , (26, "douazecisisase")
+      , (27, "douazecisisapte")
+      , (28, "douazecisiopt")
+      , (29, "douazecisinoua")
+      , (30, "treizeci")
+      , (31, "treizecisiunu")
+      , (32, "treizecisidoi")
+      , (33, "treizecisitrei")
+      , (34, "treizecisipatru")
+      , (35, "treizecisicinci")
+      , (36, "treizecisisase")
+      , (37, "treizecisisapte")
+      , (38, "treizecisiopt")
+      , (39, "treizecisinoua")
+      , (40, "patruzeci")
+      , (41, "patruzecisiunu")
+      , (42, "patruzecisidoi")
+      , (43, "patruzecisitrei")
+      , (44, "patruzecisipatru")
+      , (45, "patruzecisicinci")
+      , (46, "patruzecisisase")
+      , (47, "patruzecisisapte")
+      , (48, "patruzecisiopt")
+      , (49, "patruzecisinoua")
+      , (50, "cincizeci")
+      , (51, "cincizecisiunu")
+      , (52, "cincizecisidoi")
+      , (53, "cincizecisitrei")
+      , (54, "cincizecisipatru")
+      , (55, "cincizecisicinci")
+      , (56, "cincizecisisase")
+      , (57, "cincizecisisapte")
+      , (58, "cincizecisiopt")
+      , (59, "cincizecisinoua")
+      , (60, "saizeci")
+      , (61, "saizecisiunu")
+      , (62, "saizecisidoi")
+      , (63, "saizecisitrei")
+      , (64, "saizecisipatru")
+      , (65, "saizecisicinci")
+      , (66, "saizecisisase")
+      , (67, "saizecisisapte")
+      , (68, "saizecisiopt")
+      , (69, "saizecisinoua")
+      , (70, "saptezeci")
+      , (71, "saptezecisiunu")
+      , (72, "saptezecisidoi")
+      , (73, "saptezecisitrei")
+      , (74, "saptezecisipatru")
+      , (75, "saptezecisicinci")
+      , (76, "saptezecisisase")
+      , (77, "saptezecisisapte")
+      , (78, "saptezecisiopt")
+      , (79, "saptezecisinoua")
+      , (80, "optzeci")
+      , (81, "optzecisiunu")
+      , (82, "optzecisidoi")
+      , (83, "optzecisitrei")
+      , (84, "optzecisipatru")
+      , (85, "optzecisicinci")
+      , (86, "optzecisisase")
+      , (87, "optzecisisapte")
+      , (88, "optzecisiopt")
+      , (89, "optzecisinoua")
+      , (90, "nouazeci")
+      , (91, "nouazecisiunu")
+      , (92, "nouazecisidoi")
+      , (93, "nouazecisitrei")
+      , (94, "nouazecisipatru")
+      , (95, "nouazecisicinci")
+      , (96, "nouazecisisase")
+      , (97, "nouazecisisapte")
+      , (98, "nouazecisiopt")
+      , (99, "nouazecisinoua")
+      , (100, "o suta")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/RU/TestData.hs b/src-test/Text/Numeral/Language/RU/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/RU/TestData.hs
@@ -0,0 +1,192 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        ru
+
+[@ISO639-2@]        rus
+
+[@ISO639-3@]        rus
+
+[@Native name@]     Русский язык
+
+[@English name@]    Russian
+-}
+
+module Text.Numeral.Language.RU.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://en.wikibooks.org/wiki/Russian/Numbers
+  http://russian.speak7.com/russian_numbers.htm
+  http://learningrussian.net/games_verbs_grammar3.php
+  http://www.waytorussia.net/WhatIsRussia/Russian/Part1a.html
+-}
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "ноль")
+      , (1, "один")
+      , (2, "два")
+      , (3, "три")
+      , (4, "четыре")
+      , (5, "пять")
+      , (6, "шесть")
+      , (7, "семь")
+      , (8, "восемь")
+      , (9, "девять")
+      , (10, "десять")
+      , (11, "одиннадцать")
+      , (12, "двенадцать")
+      , (13, "тринадцать")
+      , (14, "четырнадцать")
+      , (15, "пятнадцать")
+      , (16, "шестнадцать")
+      , (17, "семнадцать")
+      , (18, "восемнадцать")
+      , (19, "девятнадцать")
+      , (20, "двадцать")
+      , (21, "двадцать один")
+      , (22, "двадцать два")
+      , (23, "двадцать три")
+      , (24, "двадцать четыре")
+      , (25, "двадцать пять")
+      , (26, "двадцать шесть")
+      , (27, "двадцать семь")
+      , (28, "двадцать восемь")
+      , (29, "двадцать девять")
+      , (30, "тридцать")
+      , (31, "тридцать один")
+      , (32, "тридцать два")
+      , (33, "тридцать три")
+      , (34, "тридцать четыре")
+      , (35, "тридцать пять")
+      , (36, "тридцать шесть")
+      , (37, "тридцать семь")
+      , (38, "тридцать восемь")
+      , (39, "тридцать девять")
+      , (40, "сорок")
+      , (41, "сорок один")
+      , (42, "сорок два")
+      , (43, "сорок три")
+      , (44, "сорок четыре")
+      , (45, "сорок пять")
+      , (46, "сорок шесть")
+      , (47, "сорок семь")
+      , (48, "сорок восемь")
+      , (49, "сорок девять")
+      , (50, "пятьдесят")
+      , (51, "пятьдесят один")
+      , (52, "пятьдесят два")
+      , (53, "пятьдесят три")
+      , (54, "пятьдесят четыре")
+      , (55, "пятьдесят пять")
+      , (56, "пятьдесят шесть")
+      , (57, "пятьдесят семь")
+      , (58, "пятьдесят восемь")
+      , (59, "пятьдесят девять")
+      , (60, "шестьдесят")
+      , (61, "шестьдесят один")
+      , (62, "шестьдесят два")
+      , (63, "шестьдесят три")
+      , (64, "шестьдесят четыре")
+      , (65, "шестьдесят пять")
+      , (66, "шестьдесят шесть")
+      , (67, "шестьдесят семь")
+      , (68, "шестьдесят восемь")
+      , (69, "шестьдесят девять")
+      , (70, "семьдесят")
+      , (71, "семьдесят один")
+      , (72, "семьдесят два")
+      , (73, "семьдесят три")
+      , (74, "семьдесят четыре")
+      , (75, "семьдесят пять")
+      , (76, "семьдесят шесть")
+      , (77, "семьдесят семь")
+      , (78, "семьдесят восемь")
+      , (79, "семьдесят девять")
+      , (80, "восемьдесят")
+      , (81, "восемьдесят один")
+      , (82, "восемьдесят два")
+      , (83, "восемьдесят три")
+      , (84, "восемьдесят четыре")
+      , (85, "восемьдесят пять")
+      , (86, "восемьдесят шесть")
+      , (87, "восемьдесят семь")
+      , (88, "восемьдесят восемь")
+      , (89, "восемьдесят девять")
+      , (90, "девяносто")
+      , (91, "девяносто один")
+      , (92, "девяносто два")
+      , (93, "девяносто три")
+      , (94, "девяносто четыре")
+      , (95, "девяносто пять")
+      , (96, "девяносто шесть")
+      , (97, "девяносто семь")
+      , (98, "девяносто восемь")
+      , (99, "девяносто девять")
+      , (100, "сто")
+      , (101, "сто один")
+      , (108, "сто восемь")
+      , (110, "сто десять")
+      , (115, "сто пятнадцать")
+      , (121, "сто двадцать один")
+      , (133, "сто тридцать три")
+      , (147, "сто сорок семь")
+      , (200, "двести")
+      , (300, "триста")
+      , (400, "четыреста")
+      , (500, "пятьсот")
+      , (600, "шестьсот")
+      , (700, "семьсот")
+      , (800, "восемьсот")
+      , (900, "девятьсот")
+      , (1000, "тысяча")
+      , (2000, "две тысячи")
+      , (3000, "три тысячи")
+      , (5000, "пять тысяч")
+      , (6000, "шесть тысяч")
+      , (9000, "девять тысяч")
+      , (16000, "шестнадцать тысяч")
+      , (21000, "двадцать одна тысяча")
+      , (22000, "двадцать две тысячи")
+      , (23000, "двадцать три тысячи")
+      , (28000, "двадцать восемь тысяч")
+      , (41000, "сорок одна тысяча")
+      , (42000, "сорок две тысячи")
+      , (49000, "сорок девять тысяч")
+      , (100000, "сто тысяч")
+      , (200000, "двести тысяч")
+      , (300000, "триста тысяч")
+      , (300001, "триста тысяч один")
+      , (300020, "триста тысяч двадцать")
+      , (300825, "триста тысячь восемьсот двадцать пять")
+      , (dec 6, "один миллион")
+      , (2 ⋅ dec 6, "два миллиона")
+      , (5 ⋅ dec 6, "пять миллионов")
+      , (dec 9, "один миллиард")
+      , (2 ⋅ dec 9, "два миллиарда")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/SCO/TestData.hs b/src-test/Text/Numeral/Language/SCO/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/SCO/TestData.hs
@@ -0,0 +1,146 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        sco
+
+[@ISO639-3@]        sco
+
+[@Native name@]     Scots
+
+[@English name@]    Scots
+-}
+
+module Text.Numeral.Language.SCO.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.sf.airnet.ne.jp/~ts/language/number/scots.html
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "ane")
+      , (2, "twa")
+      , (3, "three")
+      , (4, "fower")
+      , (5, "five")
+      , (6, "sax")
+      , (7, "seeven")
+      , (8, "echt")
+      , (9, "nine")
+      , (10, "ten")
+      , (11, "aleeven")
+      , (12, "twal")
+      , (13, "therteen")
+      , (14, "fowerteen")
+      , (15, "feifteen")
+      , (16, "saxteen")
+      , (17, "seiventeen")
+      , (18, "echteen")
+      , (19, "ninteen")
+      , (20, "twintie")
+      , (21, "twintie ane")
+      , (22, "twintie twa")
+      , (23, "twintie three")
+      , (24, "twintie fower")
+      , (25, "twintie five")
+      , (26, "twintie sax")
+      , (27, "twintie seeven")
+      , (28, "twintie echt")
+      , (29, "twintie nine")
+      , (30, "thertie")
+      , (31, "thertie ane")
+      , (32, "thertie twa")
+      , (33, "thertie three")
+      , (34, "thertie fower")
+      , (35, "thertie five")
+      , (36, "thertie sax")
+      , (37, "thertie seeven")
+      , (38, "thertie echt")
+      , (39, "thertie nine")
+      , (40, "fowertie")
+      , (41, "fowertie ane")
+      , (42, "fowertie twa")
+      , (43, "fowertie three")
+      , (44, "fowertie fower")
+      , (45, "fowertie five")
+      , (46, "fowertie sax")
+      , (47, "fowertie seeven")
+      , (48, "fowertie echt")
+      , (49, "fowertie nine")
+      , (50, "fuftie")
+      , (51, "fuftie ane")
+      , (52, "fuftie twa")
+      , (53, "fuftie three")
+      , (54, "fuftie fower")
+      , (55, "fuftie five")
+      , (56, "fuftie sax")
+      , (57, "fuftie seeven")
+      , (58, "fuftie echt")
+      , (59, "fuftie nine")
+      , (60, "saxtie")
+      , (61, "saxtie ane")
+      , (62, "saxtie twa")
+      , (63, "saxtie three")
+      , (64, "saxtie fower")
+      , (65, "saxtie five")
+      , (66, "saxtie sax")
+      , (67, "saxtie seeven")
+      , (68, "saxtie echt")
+      , (69, "saxtie nine")
+      , (70, "seeventie")
+      , (71, "seeventie ane")
+      , (72, "seeventie twa")
+      , (73, "seeventie three")
+      , (74, "seeventie fower")
+      , (75, "seeventie five")
+      , (76, "seeventie sax")
+      , (77, "seeventie seeven")
+      , (78, "seeventie echt")
+      , (79, "seeventie nine")
+      , (80, "echtie")
+      , (81, "echtie ane")
+      , (82, "echtie twa")
+      , (83, "echtie three")
+      , (84, "echtie fower")
+      , (85, "echtie five")
+      , (86, "echtie sax")
+      , (87, "echtie seeven")
+      , (88, "echtie echt")
+      , (89, "echtie nine")
+      , (90, "nintie")
+      , (91, "nintie ane")
+      , (92, "nintie twa")
+      , (93, "nintie three")
+      , (94, "nintie fower")
+      , (95, "nintie five")
+      , (96, "nintie sax")
+      , (97, "nintie seeven")
+      , (98, "nintie echt")
+      , (99, "nintie nine")
+      , (100, "hunner")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/SV/TestData.hs b/src-test/Text/Numeral/Language/SV/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/SV/TestData.hs
@@ -0,0 +1,308 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        sv
+
+[@ISO639-2B@]       swe
+
+[@ISO639-3@]        swe
+
+[@Native name@]     svenska
+
+[@English name@]    Swedish
+-}
+
+module Text.Numeral.Language.SV.TestData
+    ( cardinals
+    , ordinals
+    , partitives
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "base-unicode-symbols" Prelude.Unicode ( (⋅) )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Grammar ( neuter, common )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+-- Sources:
+--   http://en.wikipedia.org/wiki/Swedish_grammar#Numerals
+--   http://publications.europa.eu/code/sv/sv-4100600sv.htm
+--   http://www.lysator.liu.se/language/Languages/Swedish/Grammar.html#numbers
+--   http://en.wikibooks.org/wiki/Swedish/Numerals
+--   http://www.speakswedish.co.uk/vocab/numbers
+--   http://aclweb.org/anthology/C/C73/C73-2031.pdf
+--
+-- Rules for writing large words seem hard to come by online.
+-- http://publications.europa.eu/code/sv/sv-4100600sv.htm provides
+-- some guidelines:
+--
+-- Rule 1: Even hundreds, thousands, and so on, are generally written
+-- as two words: två tusen, fyra hundra, sex miljoner
+--
+-- Rule 2: Numbers smaller than one hundred are always written as one
+-- word, as are other number under one million: fyrtiosju,
+-- niotusenfemhundrasexton
+--
+-- Rule 3: Numbers larger than one million should be written so that
+-- the words tusen, miljon, miljard, and so on always stand on their
+-- own: tjugofem miljarder tre miljoner
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "neuter"
+    , neuter defaultInflection
+      -- Rule 2 (one word)
+    , [ (0, "noll")
+      , (1, "ett")
+      , (2, "två")
+      , (3, "tre")
+      , (4, "fyra")
+      , (5, "fem")
+      , (6, "sex")
+      , (7, "sju")
+      , (8, "åtta")
+      , (9, "nio")
+      , (10, "tio")
+      , (11, "elva")
+      , (12, "tolv")
+      , (13, "tretton")
+      , (14, "fjorton")
+      , (15, "femton")
+      , (16, "sexton")
+      , (17, "sjutton")
+      , (18, "arton")
+      , (19, "nitton")
+      , (20, "tjugo")
+      , (21, "tjugoett")
+      , (22, "tjugotvå")
+      , (23, "tjugotre")
+      , (24, "tjugofyra")
+      , (25, "tjugofem")
+      , (26, "tjugosex")
+      , (27, "tjugosju")
+      , (28, "tjugoåtta")
+      , (29, "tjugonio")
+      , (30, "trettio")
+      , (31, "trettioett")
+      , (32, "trettiotvå")
+      , (33, "trettiotre")
+      , (34, "trettiofyra")
+      , (35, "trettiofem")
+      , (36, "trettiosex")
+      , (37, "trettiosju")
+      , (38, "trettioåtta")
+      , (39, "trettionio")
+      , (40, "fyrtio")
+      , (41, "fyrtioett")
+      , (42, "fyrtiotvå")
+      , (43, "fyrtiotre")
+      , (44, "fyrtiofyra")
+      , (45, "fyrtiofem")
+      , (46, "fyrtiosex")
+      , (47, "fyrtiosju")
+      , (48, "fyrtioåtta")
+      , (49, "fyrtionio")
+      , (50, "femtio")
+      , (51, "femtioett")
+      , (52, "femtiotvå")
+      , (53, "femtiotre")
+      , (54, "femtiofyra")
+      , (55, "femtiofem")
+      , (56, "femtiosex")
+      , (57, "femtiosju")
+      , (58, "femtioåtta")
+      , (59, "femtionio")
+      , (60, "sextio")
+      , (61, "sextioett")
+      , (62, "sextiotvå")
+      , (63, "sextiotre")
+      , (64, "sextiofyra")
+      , (65, "sextiofem")
+      , (66, "sextiosex")
+      , (67, "sextiosju")
+      , (68, "sextioåtta")
+      , (69, "sextionio")
+      , (70, "sjuttio")
+      , (71, "sjuttioett")
+      , (72, "sjuttiotvå")
+      , (73, "sjuttiotre")
+      , (74, "sjuttiofyra")
+      , (75, "sjuttiofem")
+      , (76, "sjuttiosex")
+      , (77, "sjuttiosju")
+      , (78, "sjuttioåtta")
+      , (79, "sjuttionio")
+      , (80, "åttio")
+      , (81, "åttioett")
+      , (82, "åttiotvå")
+      , (83, "åttiotre")
+      , (84, "åttiofyra")
+      , (85, "åttiofem")
+      , (86, "åttiosex")
+      , (87, "åttiosju")
+      , (88, "åttioåtta")
+      , (89, "åttionio")
+      , (90, "nittio")
+      , (91, "nittioett")
+      , (92, "nittiotvå")
+      , (93, "nittiotre")
+      , (94, "nittiofyra")
+      , (95, "nittiofem")
+      , (96, "nittiosex")
+      , (97, "nittiosju")
+      , (98, "nittioåtta")
+      , (99, "nittionio")
+      , (101, "etthundraett")
+      , (102, "etthundratvå")
+      , (549, "femhundrafyrtionio")
+        -- "ettusen" is a special spelling case where "ett tusen"
+        -- written as one word becomes ettusen, dropping one 't'.
+      , (1349, "ettusentrehundrafyrtionio")
+      , (3502, "tretusenfemhundratvå")
+      , (9516, "niotusenfemhundrasexton")
+      , (30934, "trettiotusenniohundratrettiofyra")
+      , (837132, "åttahundratrettiosjutusenetthundratrettiotvå")
+      , (999999, "niohundranittioniotusenniohundranittionio")
+        -- Rule 1 (even hundreds and so on)
+      , (100, "ett hundra")
+      , (200, "två hundra")
+      , (300, "tre hundra")
+      , (500, "fem hundra")
+      , (600, "sex hundra")
+      , (800, "åtta hundra")
+      , (1000, "ett tusen")
+      , (3000, "tre tusen")
+      , (5000, "fem tusen")
+      , (10000, "tio tusen")
+      , (20000, "tjugo tusen")
+      , (50000, "femtio tusen")
+      , (dec 5, "etthundra tusen")
+      , (dec 6, "en miljon")
+      , (2 ⋅ dec 6, "två miljoner")
+      , (10 ⋅ dec 6, "tio miljoner")
+      , (dec 8, "etthundra miljoner")
+      , (2 ⋅ dec 8, "tvåhundra miljoner")
+      , (dec 9, "en miljard")
+      , (dec 12, "en biljon")
+      , (dec 15, "en biljard")
+      , (dec 18, "en triljon")
+      , (dec 24, "en kvadriljon")
+      , (dec 30, "en kvintiljon")
+      , (dec 36, "en sextiljon")
+      , (dec 42, "en septiljon")
+      , (dec 48, "en oktiljon")
+      , (dec 54, "en noniljon")
+      , (dec 60, "en deciljon")
+      , (dec 66, "en undeciljon")
+        -- Rule 3: Numbers larger than one million split up on tusen, miljon, etc
+      , (123456789, "etthundratjugotre miljoner fyrahundrafemtiosex tusen sjuhundraåttionio")
+      , (37149204, "trettiosju miljoner etthundrafyrtionio tusen tvåhundrafyra")
+      , (302145568, "trehundratvå miljoner etthundrafyrtiofem tusen femhundrasextioåtta")
+      , (1000100, "en miljon etthundra")
+      , (1305100, "en miljon trehundrafem tusen etthundra")
+      , (300000102, "trehundra miljoner etthundratvå")
+      , (300500000, "trehundra miljoner femhundra tusen")
+      , (25003000000, "tjugofem miljarder tre miljoner")
+      ]
+    )
+  , ( "common"
+    , common defaultInflection
+    , [ (1, "en")
+      , (21, "tjugoen")
+      ]
+    )
+  ]
+
+ordinals ∷ (Integral i) ⇒ TestData i
+ordinals =
+  [ ( "neuter"
+    , neuter defaultInflection
+    , [ (0, "nollte")
+      , (1, "första")
+      , (2, "andra")
+      , (3, "tredje")
+      , (4, "fjärde")
+      , (5, "femte")
+      , (6, "sjätte")
+      , (7, "sjunde")
+      , (8, "åttonde")
+      , (9, "nionde")
+      , (10, "tionde")
+      , (11, "elfte")
+      , (12, "tolfte")
+      , (13, "trettonde")
+      , (14, "fjortonde")
+      , (15, "femtonde")
+      , (16, "sextonde")
+      , (17, "sjuttonde")
+      , (18, "artonde")
+      , (19, "nittonde")
+      , (20, "tjugonde")
+      , (21, "tjugoförsta")
+      , (22, "tjugoandra")
+      , (23, "tjugotredje")
+      , (30, "trettionde")
+      , (40, "fyrtionde")
+      , (50, "femtionde")
+      , (60, "sextionde")
+      , (70, "sjuttionde")
+      , (80, "åttionde")
+      , (90, "nittionde")
+      , (100, "ett hundrade")
+      , (200, "två hundrade")
+      , (500, "fem hundrade")
+      , (1000, "ett tusende")
+      , (2000, "två tusende")
+      , (5000, "fem tusende")
+      , (10000, "tio tusende")
+      , (20000, "tjugo tusende")
+      , (50000, "femtio tusende")
+      , (dec 6, "en miljonte")
+      , (dec 9, "en miljarte")
+      , (dec 12, "en biljonte")
+      , (dec 18, "en triljonte")
+      ]
+    )
+  ]
+
+partitives ∷ (Integral i) ⇒ TestData (i, i)
+partitives =
+  [ ( "default"
+    , defaultInflection
+    , [ ((1, 2), "en halv")
+      , ((1, 3), "en tredjedel")
+      , ((3, 4), "tre fjärdedelar")
+      , ((2, 5), "två femtedelar")
+      , ((5, 6), "fem sjättedelar")
+      , ((4, 7), "fyra sjundedelar")
+      , ((1, 8), "en åttondel")
+      , ((8, 9), "åtta niondelar")
+      , ((1, 10), "en tiondel")
+      , ((1, 11), "en elftedel")
+      , ((1, 12), "en tolftedel")
+      , ((1, 13), "en trettondel")
+      , ((1, 14), "en fjortondel")
+      , ((1, 15), "en femtondel")
+      , ((1, 16), "en sextondel")
+      , ((1, 17), "en sjuttondel")
+      , ((1, 18), "en artondel")
+      , ((1, 19), "en nittondel")
+      , ((1, 20), "en tjugondel")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/TAR/TestData.hs b/src-test/Text/Numeral/Language/TAR/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/TAR/TestData.hs
@@ -0,0 +1,147 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        tar
+
+[@Native name@]     Ralámuli ra'ícha
+
+[@English name@]    Central Tarahumara
+-}
+module Text.Numeral.Language.TAR.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-central-tarahumara/en/tar/
+  http://lingweb.eva.mpg.de/numeral/Tarahumara-Central.htm
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "biré")
+      , (2, "ocuá")
+      , (3, "biquiyá")
+      , (4, "nahuosa")
+      , (5, "marí")
+      , (6, "usani")
+      , (7, "quicháo")
+      , (8, "osá nahuó") -- two fours
+      , (9, "químacoy")  -- not ten
+      , (10, "macoy")
+      , (11, "macoy miná biré")
+      , (12, "macoy miná ocuá")
+      , (13, "macoy miná biquiyá")
+      , (14, "macoy miná nahuosa")
+      , (15, "macoy miná marí")
+      , (16, "macoy miná usani")
+      , (17, "macoy miná quicháo")
+      , (18, "macoy miná osá nahuó")
+      , (19, "macoy miná químacoy")
+      , (20, "osá macoy")
+      , (21, "osá macoy miná biré")
+      , (22, "osá macoy miná ocuá")
+      , (23, "osá macoy miná biquiyá")
+      , (24, "osá macoy miná nahuosa")
+      , (25, "osá macoy miná marí")
+      , (26, "osá macoy miná usani")
+      , (27, "osá macoy miná quicháo")
+      , (28, "osá macoy miná osá nahuó")
+      , (29, "osá macoy miná químacoy")
+      , (30, "baisá macoy")
+      , (31, "baisá macoy miná biré")
+      , (32, "baisá macoy miná ocuá")
+      , (33, "baisá macoy miná biquiyá")
+      , (34, "baisá macoy miná nahuosa")
+      , (35, "baisá macoy miná marí")
+      , (36, "baisá macoy miná usani")
+      , (37, "baisá macoy miná quicháo")
+      , (38, "baisá macoy miná osá nahuó")
+      , (39, "baisá macoy miná químacoy")
+      , (40, "nahuosa macoy")
+      , (41, "nahuosa macoy miná biré")
+      , (42, "nahuosa macoy miná ocuá")
+      , (43, "nahuosa macoy miná biquiyá")
+      , (44, "nahuosa macoy miná nahuosa")
+      , (45, "nahuosa macoy miná marí")
+      , (46, "nahuosa macoy miná usani")
+      , (47, "nahuosa macoy miná quicháo")
+      , (48, "nahuosa macoy miná osá nahuó")
+      , (49, "nahuosa macoy miná químacoy")
+      , (50, "marisa macoy")
+      , (51, "marisa macoy miná biré")
+      , (52, "marisa macoy miná ocuá")
+      , (53, "marisa macoy miná biquiyá")
+      , (54, "marisa macoy miná nahuosa")
+      , (55, "marisa macoy miná marí")
+      , (56, "marisa macoy miná usani")
+      , (57, "marisa macoy miná quicháo")
+      , (58, "marisa macoy miná osá nahuó")
+      , (59, "marisa macoy miná químacoy")
+      , (60, "usansa macoy")
+      , (61, "usansa macoy miná biré")
+      , (62, "usansa macoy miná ocuá")
+      , (63, "usansa macoy miná biquiyá")
+      , (64, "usansa macoy miná nahuosa")
+      , (65, "usansa macoy miná marí")
+      , (66, "usansa macoy miná usani")
+      , (67, "usansa macoy miná quicháo")
+      , (68, "usansa macoy miná osá nahuó")
+      , (69, "usansa macoy miná químacoy")
+      , (70, "quicháosa macoy")
+      , (71, "quicháosa macoy miná biré")
+      , (72, "quicháosa macoy miná ocuá")
+      , (73, "quicháosa macoy miná biquiyá")
+      , (74, "quicháosa macoy miná nahuosa")
+      , (75, "quicháosa macoy miná marí")
+      , (76, "quicháosa macoy miná usani")
+      , (77, "quicháosa macoy miná quicháo")
+      , (78, "quicháosa macoy miná osá nahuó")
+      , (79, "quicháosa macoy miná químacoy")
+        -- The "osá naósa" is from Lowland Tarahumara, not Central
+        -- Tarahumara. But this is the only available source.
+      , (80, "osá naósa macoy")
+      , (81, "osá naósa macoy miná biré")
+      , (82, "osá naósa macoy miná ocuá")
+      , (83, "osá naósa macoy miná biquiyá")
+      , (84, "osá naósa macoy miná nahuosa")
+      , (85, "osá naósa macoy miná marí")
+      , (86, "osá naósa macoy miná usani")
+      , (87, "osá naósa macoy miná quicháo")
+      , (88, "osá naósa macoy miná osá nahuó")
+      , (89, "osá naósa macoy miná químacoy")
+      , (90, "que macoisa macoy")
+      , (91, "que macoisa macoy miná biré")
+      , (92, "que macoisa macoy miná ocuá")
+      , (93, "que macoisa macoy miná biquiyá")
+      , (94, "que macoisa macoy miná nahuosa")
+      , (95, "que macoisa macoy miná marí")
+      , (96, "que macoisa macoy miná usani")
+      , (97, "que macoisa macoy miná quicháo")
+      , (98, "que macoisa macoy miná osá nahuó")
+      , (99, "que macoisa macoy miná químacoy")
+      , (100, "biré ciento")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/TR/TestData.hs b/src-test/Text/Numeral/Language/TR/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/TR/TestData.hs
@@ -0,0 +1,262 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        tr
+
+[@ISO639-2@]        tur
+
+[@ISO639-3@]        tur
+
+[@Native name@]     Türkçe
+
+[@English name@]    Turkish
+-}
+
+module Text.Numeral.Language.TR.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-turkish/en/tur/
+  http://www.sf.airnet.ne.jp/~ts/language/number/turkish.html
+  http://www.turkishlanguage.co.uk/seasons.htm#article_15
+  http://www.turkeytravelplanner.com/details/LanguageGuide/100words_lessons/100Words_10.html
+  http://en.wikibooks.org/wiki/Turkish/Numbers
+  http://tr.wikipedia.org/wiki/B%C3%BCy%C3%BCk_say%C4%B1lar%C4%B1n_adlar%C4%B1
+-}
+
+cardinals ∷ (Integral i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "sıfır")
+      , (1, "bir")
+      , (2, "iki")
+      , (3, "üç")
+      , (4, "dört")
+      , (5, "beş")
+      , (6, "altı")
+      , (7, "yedi")
+      , (8, "sekiz")
+      , (9, "dokuz")
+      , (10, "on")
+      , (11, "on bir")
+      , (12, "on iki")
+      , (13, "on üç")
+      , (14, "on dört")
+      , (15, "on beş")
+      , (16, "on altı")
+      , (17, "on yedi")
+      , (18, "on sekiz")
+      , (19, "on dokuz")
+      , (20, "yirmi")
+      , (21, "yirmi bir")
+      , (22, "yirmi iki")
+      , (23, "yirmi üç")
+      , (24, "yirmi dört")
+      , (25, "yirmi beş")
+      , (26, "yirmi altı")
+      , (27, "yirmi yedi")
+      , (28, "yirmi sekiz")
+      , (29, "yirmi dokuz")
+      , (30, "otuz")
+      , (31, "otuz bir")
+      , (32, "otuz iki")
+      , (33, "otuz üç")
+      , (34, "otuz dört")
+      , (35, "otuz beş")
+      , (36, "otuz altı")
+      , (37, "otuz yedi")
+      , (38, "otuz sekiz")
+      , (39, "otuz dokuz")
+      , (40, "kırk")
+      , (41, "kırk bir")
+      , (42, "kırk iki")
+      , (43, "kırk üç")
+      , (44, "kırk dört")
+      , (45, "kırk beş")
+      , (46, "kırk altı")
+      , (47, "kırk yedi")
+      , (48, "kırk sekiz")
+      , (49, "kırk dokuz")
+      , (50, "elli")
+      , (51, "elli bir")
+      , (52, "elli iki")
+      , (53, "elli üç")
+      , (54, "elli dört")
+      , (55, "elli beş")
+      , (56, "elli altı")
+      , (57, "elli yedi")
+      , (58, "elli sekiz")
+      , (59, "elli dokuz")
+      , (60, "altmış")
+      , (61, "altmış bir")
+      , (62, "altmış iki")
+      , (63, "altmış üç")
+      , (64, "altmış dört")
+      , (65, "altmış beş")
+      , (66, "altmış altı")
+      , (67, "altmış yedi")
+      , (68, "altmış sekiz")
+      , (69, "altmış dokuz")
+      , (70, "yetmiş")
+      , (71, "yetmiş bir")
+      , (72, "yetmiş iki")
+      , (73, "yetmiş üç")
+      , (74, "yetmiş dört")
+      , (75, "yetmiş beş")
+      , (76, "yetmiş altı")
+      , (77, "yetmiş yedi")
+      , (78, "yetmiş sekiz")
+      , (79, "yetmiş dokuz")
+      , (80, "seksen")
+      , (81, "seksen bir")
+      , (82, "seksen iki")
+      , (83, "seksen üç")
+      , (84, "seksen dört")
+      , (85, "seksen beş")
+      , (86, "seksen altı")
+      , (87, "seksen yedi")
+      , (88, "seksen sekiz")
+      , (89, "seksen dokuz")
+      , (90, "doksan")
+      , (91, "doksan bir")
+      , (92, "doksan iki")
+      , (93, "doksan üç")
+      , (94, "doksan dört")
+      , (95, "doksan beş")
+      , (96, "doksan altı")
+      , (97, "doksan yedi")
+      , (98, "doksan sekiz")
+      , (99, "doksan dokuz")
+      , (100, "yüz")
+      , (200, "iki yüz")
+      , (300, "üç yüz")
+      , (400, "dört yüz")
+      , (500, "beş yüz")
+      , (600, "altı yüz")
+      , (700, "yedi yüz")
+      , (800, "sekiz yüz")
+      , (900, "dokuz yüz")
+      , (1000, "bin")
+      , (2000, "iki bin")
+      , (3000, "üç bin")
+      , (4000, "dört bin")
+      , (5000, "beş bin")
+      , (6000, "altı bin")
+      , (7000, "yedi bin")
+      , (8000, "sekiz bin")
+      , (9000, "dokuz bin")
+      , (10000, "on bin")
+      , (11000, "onbir bin")
+      , (12000, "oniki bin")
+      , (13000, "onüç bin")
+      , (14000, "ondört bin")
+      , (15000, "onbeş bin")
+      , (16000, "onaltı bin")
+      , (17000, "onyedi bin")
+      , (18000, "onsekiz bin")
+      , (19000, "ondokuz bin")
+      , (20000, "yirmi bin")
+      , (21000, "yirmi bir bin")
+      , (22000, "yirmi iki bin")
+      , (23000, "yirmi üç bin")
+      , (24000, "yirmi dört bin")
+      , (25000, "yirmi beş bin")
+      , (26000, "yirmi altı bin")
+      , (27000, "yirmi yedi bin")
+      , (28000, "yirmi sekiz bin")
+      , (30000, "otuz bin")
+      , (50000, "elli bin")
+      , (100000, "yüz bin")
+      , (523758, "beş yüz yirmi üç bin yedi yüz elli sekiz")
+      , (dec 6, "bir milyon")
+      , (123456789, "yüz yirmi üç milyon dört yüz elli altı bin yedi yüz seksen dokuz")
+      , (dec 9, "bir bilyon")
+      , (dec 12, "bir trilyon")
+      , (dec 15, "bir katrilyon")
+      , (dec 18, "bir kentilyon")
+      , (dec 21, "bir sekstilyon")
+      , (dec 24, "bir septilyon")
+      , (dec 27, "bir oktilyon")
+      , (dec 30, "bir nonilyon")
+      , (dec 33, "bir desilyon")
+      , (dec 36, "bir andesilyon")
+      , (dec 39, "bir dodesilyon")
+      , (dec 42, "bir tredesilyon")
+      , (dec 45, "bir katordesilyon")
+      , (dec 48, "bir kendesilyon")
+      , (dec 51, "bir seksdesilyon")
+      , (dec 54, "bir septendesilyon")
+      , (dec 57, "bir oktodesilyon")
+      , (dec 60, "bir novemdesilyon")
+      , (dec 63, "bir vigintilyon")
+      , (dec 66, "bir anvigintilyon")
+      , (dec 69, "bir dovigintilyon")
+      , (dec 72, "bir tresvigintilyon")
+      , (dec 75, "bir katorvigintilyon")
+      , (dec 78, "bir kenkavigintilyon")
+      , (dec 81, "bir sesvigintilyon")
+      , (dec 84, "bir septemvigintilyon")
+      , (dec 87, "bir oktovigintilyon")
+      , (dec 90, "bir novemvigintilyon")
+      , (dec 93, "bir trigintilyon")
+      , (dec 96, "bir antrigintilyon")
+      , (dec 99, "bir dotrigintilyon")
+      , (dec 102, "bir trestrigintilyon")
+      , (dec 105, "bir katortrigintilyon")
+      , (dec 108, "bir kenkatrigintilyon")
+      , (dec 111, "bir sestrigintilyon")
+      , (dec 114, "bir septemtrigintilyon")
+      , (dec 117, "bir oktotrigintilyon")
+      , (dec 120, "bir novemtrigintilyon")
+      , (dec 123, "bir katragintilyon")
+      , (dec 153, "bir kenkagintilyon")
+      , (dec 183, "bir seksagintilyon")
+      , (dec 213, "bir septegintilyon")
+      , (dec 243, "bir oktogintilyon")
+      , (dec 273, "bir nonagintilyon")
+      , (dec 303, "bir sentilyon")
+      , (dec 306, "bir ansentilyon")
+      , (dec 309, "bir dosentilyon")
+      , (dec 312, "bir tresentilyon")
+      , (dec 333, "bir desisentilyon")
+      , (dec 336, "bir andesisentilyon")
+      , (dec 363, "bir vigintisentilyon")
+      , (dec 366, "bir anvigintisentilyon")
+      , (dec 393, "bir trigintasentilyon")
+      , (dec 423, "bir katragintasentilyon")
+      , (dec 453, "bir kenkagintasentilyon")
+      , (dec 483, "bir seksagintasentilyon")
+      , (dec 513, "bir septegintasentilyon")
+      , (dec 543, "bir oktogintasentilyon")
+      , (dec 573, "bir nonagintasentilyon")
+      , (dec 603, "bir dusentilyon")
+      -- , (dec 903, "bir tresentilyon") -- same as 10 ^ 312
+      , (dec 1203, "bir katringentilyon")
+      , (dec 1503, "bir kengentilyon")
+      , (dec 1803, "bir sesentilyon")
+      , (dec 2103, "bir septingentilyon")
+      , (dec 2403, "bir oktingentilyon")
+      , (dec 2703, "bir nongentilyon")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/WO/TestData.hs b/src-test/Text/Numeral/Language/WO/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/WO/TestData.hs
@@ -0,0 +1,174 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        wo
+
+[@ISO639-2@]        wo1
+
+[@ISO639-3@]        wo1
+
+[@Native name@]     Wolof
+
+[@English name@]    Wolof
+-}
+
+module Text.Numeral.Language.WO.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://en.wikipedia.org/wiki/Wolof_language#Numerals
+  http://www.sf.airnet.ne.jp/~ts/language/number/wolof.html
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "benn")
+      , (2, "ñaar")
+      , (3, "ñett")
+      , (4, "ñeent")
+      , (5, "juróom")
+      , (6, "juróom-benn")
+      , (7, "juróom-ñaar")
+      , (8, "juróom-ñett")
+      , (9, "juróom-ñeent")
+      , (10, "fukk")
+      , (11, "fukk ak benn")
+      , (12, "fukk ak ñaar")
+      , (13, "fukk ak ñett")
+      , (14, "fukk ak ñeent")
+      , (15, "fukk ak juróom")
+      , (16, "fukk ak juróom-benn")
+      , (17, "fukk ak juróom-ñaar")
+      , (18, "fukk ak juróom-ñett")
+      , (19, "fukk ak juróom-ñeent")
+      , (20, "ñaar-fukk")
+      , (21, "ñaar-fukk ak benn")
+      , (22, "ñaar-fukk ak ñaar")
+      , (23, "ñaar-fukk ak ñett")
+      , (24, "ñaar-fukk ak ñeent")
+      , (25, "ñaar-fukk ak juróom")
+      , (26, "ñaar-fukk ak juróom-benn")
+      , (27, "ñaar-fukk ak juróom-ñaar")
+      , (28, "ñaar-fukk ak juróom-ñett")
+      , (29, "ñaar-fukk ak juróom-ñeent")
+      , (30, "ñett-fukk")
+      , (31, "ñett-fukk ak benn")
+      , (32, "ñett-fukk ak ñaar")
+      , (33, "ñett-fukk ak ñett")
+      , (34, "ñett-fukk ak ñeent")
+      , (35, "ñett-fukk ak juróom")
+      , (36, "ñett-fukk ak juróom-benn")
+      , (37, "ñett-fukk ak juróom-ñaar")
+      , (38, "ñett-fukk ak juróom-ñett")
+      , (39, "ñett-fukk ak juróom-ñeent")
+      , (40, "ñeent-fukk")
+      , (41, "ñeent-fukk ak benn")
+      , (42, "ñeent-fukk ak ñaar")
+      , (43, "ñeent-fukk ak ñett")
+      , (44, "ñeent-fukk ak ñeent")
+      , (45, "ñeent-fukk ak juróom")
+      , (46, "ñeent-fukk ak juróom-benn")
+      , (47, "ñeent-fukk ak juróom-ñaar")
+      , (48, "ñeent-fukk ak juróom-ñett")
+      , (49, "ñeent-fukk ak juróom-ñeent")
+      , (50, "juróom-fukk")
+      , (51, "juróom-fukk ak benn")
+      , (52, "juróom-fukk ak ñaar")
+      , (53, "juróom-fukk ak ñett")
+      , (54, "juróom-fukk ak ñeent")
+      , (55, "juróom-fukk ak juróom")
+      , (56, "juróom-fukk ak juróom-benn")
+      , (57, "juróom-fukk ak juróom-ñaar")
+      , (58, "juróom-fukk ak juróom-ñett")
+      , (59, "juróom-fukk ak juróom-ñeent")
+      , (60, "juróom-benn-fukk")
+      , (61, "juróom-benn-fukk ak benn")
+      , (62, "juróom-benn-fukk ak ñaar")
+      , (63, "juróom-benn-fukk ak ñett")
+      , (64, "juróom-benn-fukk ak ñeent")
+      , (65, "juróom-benn-fukk ak juróom")
+      , (66, "juróom-benn-fukk ak juróom-benn")
+      , (67, "juróom-benn-fukk ak juróom-ñaar")
+      , (68, "juróom-benn-fukk ak juróom-ñett")
+      , (69, "juróom-benn-fukk ak juróom-ñeent")
+      , (70, "juróom-ñaar-fukk")
+      , (71, "juróom-ñaar-fukk ak benn")
+      , (72, "juróom-ñaar-fukk ak ñaar")
+      , (73, "juróom-ñaar-fukk ak ñett")
+      , (74, "juróom-ñaar-fukk ak ñeent")
+      , (75, "juróom-ñaar-fukk ak juróom")
+      , (76, "juróom-ñaar-fukk ak juróom-benn")
+      , (77, "juróom-ñaar-fukk ak juróom-ñaar")
+      , (78, "juróom-ñaar-fukk ak juróom-ñett")
+      , (79, "juróom-ñaar-fukk ak juróom-ñeent")
+      , (80, "juróom-ñett-fukk")
+      , (81, "juróom-ñett-fukk ak benn")
+      , (82, "juróom-ñett-fukk ak ñaar")
+      , (83, "juróom-ñett-fukk ak ñett")
+      , (84, "juróom-ñett-fukk ak ñeent")
+      , (85, "juróom-ñett-fukk ak juróom")
+      , (86, "juróom-ñett-fukk ak juróom-benn")
+      , (87, "juróom-ñett-fukk ak juróom-ñaar")
+      , (88, "juróom-ñett-fukk ak juróom-ñett")
+      , (89, "juróom-ñett-fukk ak juróom-ñeent")
+      , (90, "juróom-ñeent-fukk")
+      , (91, "juróom-ñeent-fukk ak benn")
+      , (92, "juróom-ñeent-fukk ak ñaar")
+      , (93, "juróom-ñeent-fukk ak ñett")
+      , (94, "juróom-ñeent-fukk ak ñeent")
+      , (95, "juróom-ñeent-fukk ak juróom")
+      , (96, "juróom-ñeent-fukk ak juróom-benn")
+      , (97, "juróom-ñeent-fukk ak juróom-ñaar")
+      , (98, "juróom-ñeent-fukk ak juróom-ñett")
+      , (99, "juróom-ñeent-fukk ak juróom-ñeent")
+      , (100, "téeméer")
+      , (101, "téeméer ak benn")
+      , (106, "téeméer ak juróom-benn")
+      , (110, "téeméer ak fukk")
+      , (200, "ñaari téeméer")
+      , (300, "ñetti téeméer")
+      , (400, "ñeenti téeméer")
+      , (500, "juróomi téeméer")
+      , (600, "juróom-benni téeméer")
+      , (700, "juróom-ñaari téeméer")
+      , (800, "juróom-ñetti téeméer")
+      , (900, "juróom-ñeenti téeméer")
+      , (1000, "junni")
+      , (1100, "junni ak téeméer")
+      , (1600, "junni ak juróom-benni téeméer")
+      , (1945, "junni ak juróom-ñeenti téeméer ak ñeent-fukk ak juróom")
+      , (1969, "junni ak juróom-ñeenti téeméer ak juróom-benn-fukk ak juróom-ñeent")
+      , (2000, "ñaari junni")
+      , (3000, "ñetti junni")
+      , (4000, "ñeenti junni")
+      , (5000, "juróomi junni")
+      , (6000, "juróom-benni junni")
+      , (7000, "juróom-ñaari junni")
+      , (8000, "juróom-ñetti junni")
+      , (9000, "juróom-ñeenti junni")
+      , (10000, "fukki junni")
+      , (100000, "téeméeri junni")
+      , (1000000, "tamndareet")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/YOR/TestData.hs b/src-test/Text/Numeral/Language/YOR/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/YOR/TestData.hs
@@ -0,0 +1,151 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        yo
+
+[@ISO639-2@]        yor
+
+[@ISO639-3@]        yor
+
+[@Native name@]     èdè Yorùbá
+
+[@English name@]    Yoruba
+-}
+
+module Text.Numeral.Language.YOR.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "ikan")
+      , (2, "meji")
+      , (3, "meta")
+      , (4, "merin")
+      , (5, "marun")
+      , (6, "mefa")
+      , (7, "meje")
+      , (8, "mejo")
+      , (9, "mesan")
+      , (10, "mewa")
+      , (11, "mokanla")
+      , (12, "mejila")
+      , (13, "metala")
+      , (14, "merinla")
+      , (15, "medogun")
+      , (16, "merindilogun")
+      , (17, "metadilogun")
+      , (18, "mejidilogun")
+      , (19, "mokandilogun")
+      , (20, "ogun")
+      , (21, "mokanlelogun")
+      , (22, "mejilelogun")
+      , (23, "metalelogun")
+      , (24, "merinlelogun")
+      , (25, "medogbon")
+      , (26, "merindilogbon")
+      , (27, "metadilogbon")
+      , (28, "mejidilogbon")
+      , (29, "mokandilogbon")
+      , (30, "ogbon")
+      , (31, "mokanlelogbon")
+      , (32, "mejilelogbon")
+      , (33, "metalelogbon")
+      , (34, "merinlelogbon")
+      , (35, "marundilogoji")
+      , (36, "merindilogoji")
+      , (37, "metadilogoji")
+      , (38, "mejidilogoji")
+      , (39, "mokandilogoji")
+      , (40, "ogoji")
+      , (41, "mokanlelogoji")
+      , (42, "mejilelogoji")
+      , (43, "metalelogoji")
+      , (44, "merinlelogoji")
+      , (45, "marundiladota")
+      , (46, "merindiladota")
+      , (47, "metadiladota")
+      , (48, "mejidiladota")
+      , (49, "mokandiladota")
+      , (50, "adota")
+      , (51, "mokanleladota")
+      , (52, "mejileladota")
+      , (53, "metaleladota")
+      , (54, "merinleladota")
+      , (55, "marundilogota")
+      , (56, "merindilogota")
+      , (57, "metadilogota")
+      , (58, "mejidilogota")
+      , (59, "mokandilogota")
+      , (60, "ogota")
+      , (61, "mokanlelogota")
+      , (62, "mejilelogota")
+      , (63, "metalelogota")
+      , (64, "merinlelogota")
+      , (65, "marundiladorin")
+      , (66, "merindiladorin")
+      , (67, "metadiladorin")
+      , (68, "mejidiladorin")
+      , (69, "mokandiladorin")
+      , (70, "adorin")
+      , (71, "mokanleladorin")
+      , (72, "mejileladorin")
+      , (73, "metaleladorin")
+      , (74, "merinleladorin")
+      , (75, "marundilogorin")
+      , (76, "merindilogorin")
+      , (77, "metadilogorin")
+      , (78, "mejidilogorin")
+      , (79, "mokandilogorin")
+      , (80, "ogorin")
+      , (81, "mokanlelogorin")
+      , (82, "mejilelogorin")
+      , (83, "metalelogorin")
+      , (84, "merinlelogorin")
+      , (85, "marundiladorun")
+      , (86, "merindiladorun")
+      , (87, "metadiladorun")
+      , (88, "mejidiladorun")
+      , (89, "mokandiladorun")
+      , (90, "adorun")
+      , (91, "mokanleladorun")
+      , (92, "mejileladorun")
+      , (93, "metaleladorun")
+      , (94, "merinleladorun")
+      , (95, "marundilogorun")
+      , (96, "merindilogorun")
+      , (97, "metadilogorun")
+      , (98, "mejidilogorun")
+      , (99, "mokandilogorun")
+      , (100, "ogorun")
+      , (200, "ogorun meji")
+      , (300, "ogorun meta")
+      , (400, "ogorun merin")
+      , (500, "ogorun marun")
+      , (600, "ogorun mefa")
+      , (700, "ogorun meje")
+      , (800, "ogorun mejo")
+      , (900, "ogorun mesan")
+      , (1000, "egberun")
+      ]
+    )
+  ]
+
diff --git a/src-test/Text/Numeral/Language/ZAQ/TestData.hs b/src-test/Text/Numeral/Language/ZAQ/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/ZAQ/TestData.hs
@@ -0,0 +1,167 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        zaq
+
+[@Native name@]     -
+
+[@English name@]    Aloápam Zapotec
+-}
+module Text.Numeral.Language.ZAQ.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-aloapam-zapotec/en/zaq/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "ttubi")
+      , (2, "chupa")
+      , (3, "tsunna")
+      , (4, "ttapa")
+      , (5, "gayu")
+      , (6, "xxupa")
+      , (7, "gasi")
+      , (8, "xxunu")
+      , (9, "jaa")
+      , (10, "tsii")
+      , (11, "sinia")
+      , (12, "tsi’inu")
+      , (13, "tsi’intsagüi")
+      , (14, "sitá")
+      , (15, "tsinu")
+      , (16, "sixupa")
+      , (17, "tsini")
+      , (18, "sixunu")
+      , (19, "chennia")
+      , (20, "galhia")
+      , (21, "ttuerua")
+      , (22, "chuperua")
+      , (23, "tsunerua")
+      , (24, "ttaperua")
+      , (25, "gayuerua")
+      , (26, "xxuperua")
+      , (27, "gasierua")
+      , (28, "xxunuerua")
+      , (29, "jaerua")
+      , (30, "rerua")
+      , (31, "rerua yu’u ttu")
+      , (32, "rerua yu’u chupa")
+      , (33, "rerua yu’u tsunna")
+      , (34, "rerua yu’u ttapa")
+      , (35, "rerua yu’u gayu")
+      , (36, "rerua yu’u xxupa")
+      , (37, "rerua yu’u gasi")
+      , (38, "rerua yu’u xxunu")
+      , (39, "rerua yu’u jaa")
+      , (40, "chua")
+      , (41, "chua yu’u ttu")
+      , (42, "chua yu’u chupa")
+      , (43, "chua yu’u tsunna")
+      , (44, "chua yu’u ttapa")
+      , (45, "chua yu’u gayu")
+      , (46, "chua yu’u xxupa")
+      , (47, "chua yu’u gasi")
+      , (48, "chua yu’u xxunu")
+      , (49, "chua yu’u jaa")
+      , (50, "medi gayua")
+      , (51, "medi gayua yu’u ttu")
+      , (52, "medi gayua yu’u chupa")
+      , (53, "medi gayua yu’u tsunna")
+      , (54, "medi gayua yu’u ttapa")
+      , (55, "medi gayua yu’u gayu")
+      , (56, "medi gayua yu’u xxupa")
+      , (57, "medi gayua yu’u gasi")
+      , (58, "medi gayua yu’u xxunu")
+      , (59, "medi gayua yu’u jaa")
+      , (60, "gayuna")
+      , (61, "gayuna yu’u ttu")
+      , (62, "gayuna yu’u chupa")
+      , (63, "gayuna yu’u tsunna")
+      , (64, "gayuna yu’u ttapa")
+      , (65, "gayuna yu’u gayu")
+      , (66, "gayuna yu’u xxupa")
+      , (67, "gayuna yu’u gasi")
+      , (68, "gayuna yu’u xxunu")
+      , (69, "gayuna yu’u jaa")
+      , (70, "gayuna yu’u tsii")
+      , (71, "gayuna yu’u sinia")
+      , (72, "gayuna yu’u tsi’inu")
+      , (73, "gayuna yu’u si’intse")
+      , (74, "gayuna yu’u sitá")
+      , (75, "gayuna yu’u tsinu")
+      , (76, "gayuna yu’u sixupa")
+      , (77, "gayuna yu’u tsini")
+      , (78, "gayuna yu’u sixunu")
+      , (79, "gayuna yu’u chennia")
+      , (80, "ta")
+      , (81, "ta yu’u ttu")
+      , (82, "ta yu’u chupa")
+      , (83, "ta yu’u tsunna")
+      , (84, "ta yu’u ttapa")
+      , (85, "ta yu’u gayu")
+      , (86, "ta yu’u xxupa")
+      , (87, "ta yu’u gasi")
+      , (88, "ta yu’u xxunu")
+      , (89, "ta yu’u jaa")
+      , (90, "ta yu’u tsii")
+      , (91, "ta yu’u sinia")
+      , (92, "ta yu’u tsi’inu")
+      , (93, "ta yu’u si’intse")
+      , (94, "ta yu’u sitá")
+      , (95, "ta yu’u tsinu")
+      , (96, "ta yu’u sixupa")
+      , (97, "ta yu’u tsini")
+      , (98, "ta yu’u sixunu")
+      , (99, "ta yu’u chennia")
+      , (100, "ttu gayua")
+      , (101, "ttu gayua ttubi")
+      , (102, "ttu gayua chupa")
+      , (103, "ttu gayua tsunna")
+      , (104, "ttu gayua ttapa")
+      , (105, "ttu gayua gayu")
+      , (106, "ttu gayua xxupa")
+      , (107, "ttu gayua gasi")
+      , (108, "ttu gayua xxunu")
+      , (109, "ttu gayua jaa")
+      , (110, "ttu gayua tsii")
+      , (123, "ttu gayua tsunerua")
+      , (200, "chupa gayua")
+      , (300, "tsunna gayua")
+      , (321, "tsunna gayua ttuerua")
+      , (400, "ttapa gayua")
+      , (500, "gayu gayua")
+      , (600, "xxupa gayua")
+      , (700, "gasi gayua")
+      , (800, "xxunu gayua")
+      , (900, "jaa gayua")
+      , (909, "jaa gayua jaa")
+      , (990, "jaa gayua ta yu’u tsii")
+      , (999, "jaa gayua ta yu’u chennia")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/ZH/TestData.hs b/src-test/Text/Numeral/Language/ZH/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/ZH/TestData.hs
@@ -0,0 +1,349 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        zh
+
+[@ISO639-2B@]       chi
+
+[@ISO639-2T@]       zho
+
+[@ISO639-3@]        cmn
+
+[@Native name@]     官話
+
+[@English name@]    Chinese
+-}
+
+module Text.Numeral.Language.ZH.TestData
+    ( trad_cardinals
+    , simpl_cardinals
+    , finance_trad_cardinals
+    , finance_simpl_cardinals
+    , pinyin_cardinals
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude     ( Integral )
+import "base-unicode-symbols" Data.Monoid.Unicode ( (⊕) )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "numerals" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Test ( TestData )
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.sf.airnet.ne.jp/~ts/language/number/mandarin.html
+-}
+
+-- | Cardinal numbers that are written the same using either
+-- traditional or simplified characters.
+trad_simpl_cardinals ∷ (Integral i) ⇒ [(i, Text)]
+trad_simpl_cardinals =
+  [ (0, "零")
+  , (1, "一")
+  , (2, "二")
+  , (3, "三")
+  , (4, "四")
+  , (5, "五")
+  , (6, "六")
+  , (7, "七")
+  , (8, "八")
+  , (9, "九")
+  , (10, "十")
+  , (11, "十一")
+  , (12, "十二")
+  , (13, "十三")
+  , (14, "十四")
+  , (15, "十五")
+  , (16, "十六")
+  , (17, "十七")
+  , (18, "十八")
+  , (19, "十九")
+  , (20, "二十")
+  , (21, "二十一")
+  , (22, "二十二")
+  , (23, "二十三")
+  , (24, "二十四")
+  , (25, "二十五")
+  , (26, "二十六")
+  , (27, "二十七")
+  , (28, "二十八")
+  , (29, "二十九")
+  , (30, "三十")
+  , (31, "三十一")
+  , (32, "三十二")
+  , (33, "三十三")
+  , (34, "三十四")
+  , (35, "三十五")
+  , (36, "三十六")
+  , (37, "三十七")
+  , (38, "三十八")
+  , (39, "三十九")
+  , (40, "四十")
+  , (41, "四十一")
+  , (42, "四十二")
+  , (43, "四十三")
+  , (44, "四十四")
+  , (45, "四十五")
+  , (46, "四十六")
+  , (47, "四十七")
+  , (48, "四十八")
+  , (49, "四十九")
+  , (50, "五十")
+  , (51, "五十一")
+  , (52, "五十二")
+  , (53, "五十三")
+  , (54, "五十四")
+  , (55, "五十五")
+  , (56, "五十六")
+  , (57, "五十七")
+  , (58, "五十八")
+  , (59, "五十九")
+  , (60, "六十")
+  , (61, "六十一")
+  , (62, "六十二")
+  , (63, "六十三")
+  , (64, "六十四")
+  , (65, "六十五")
+  , (66, "六十六")
+  , (67, "六十七")
+  , (68, "六十八")
+  , (69, "六十九")
+  , (100, "一百")
+  , (114, "一百十四")
+  , (200, "二百")
+  , (205, "二百〇五")
+  , (208, "二百〇八")
+  , (280, "二百八十")
+  , (301, "三百〇一")
+  , (310, "三百十")
+  , (1000, "一千")
+  , (dec 12, "一兆")
+  , (dec 16, "一京")
+  , (dec 20, "一垓")
+  , (dec 24, "一秭")
+  , (dec 28, "一穰")
+  , (dec 32, "一溝")
+  , (dec 36, "一澗")
+  , (dec 40, "一正")
+  , (dec 44, "一載")
+  ]
+
+trad_cardinals ∷ (Integral i) ⇒ TestData i
+trad_cardinals =
+  [ ( "default"
+    , defaultInflection
+    , trad_simpl_cardinals
+      ⊕ [ (2000, "兩千")
+        , (2008, "兩千〇八")
+        , (2080, "兩千〇八十")
+        , (2362, "兩千三百六十二")
+        , (2800, "兩千八百")
+        , (dec 4, "一萬")
+        , (10020, "一萬〇二十")
+        , (97375, "九萬七千三百七十五")
+        , (100004, "十萬〇四")
+        , (8734072, "八百七十三萬四千〇七十二")
+        , (10050026, "一千〇五萬〇二十六")
+        , (dec 8, "一億")
+        , (12345678902345, "十二兆三千四百五十六億七千八百九十萬兩千三百四十五")
+        ]
+    )
+  ]
+
+simpl_cardinals ∷ (Integral i) ⇒ TestData i
+simpl_cardinals =
+  [ ( "default"
+    , defaultInflection
+    , trad_simpl_cardinals
+      ⊕ [ (2000, "两千")
+        , (2008, "两千〇八")
+        , (2080, "两千〇八十")
+        , (2362, "两千三百六十二")
+        , (2800, "两千八百")
+        , (dec 4, "一万")
+        , (dec 8, "一亿")
+        ]
+    )
+  ]
+
+finance_trad_cardinals ∷ (Integral i) ⇒ TestData i
+finance_trad_cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "零")
+      , (1, "壹")
+      , (2, "貳")
+      , (3, "参")
+      , (4, "肆")
+      , (5, "伍")
+      , (6, "陸")
+      , (7, "柒")
+      , (8, "捌")
+      , (9, "玖")
+      , (10, "拾")
+      , (100, "壹伯")
+      , (1000, "壹仟")
+      , (dec 4, "壹萬")
+      , (dec 8, "壹億")
+      ]
+    )
+  ]
+
+finance_simpl_cardinals ∷ (Integral i) ⇒ TestData i
+finance_simpl_cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "零")
+      , (1, "壹")
+      , (2, "贰")
+      , (3, "参")
+      , (4, "肆")
+      , (5, "伍")
+      , (6, "陆")
+      , (7, "柒")
+      , (8, "捌")
+      , (9, "玖")
+      , (10, "拾")
+      , (100, "壹伯")
+      , (1000, "壹仟")
+      , (dec 4, "壹万")
+      , (dec 8, "壹亿")
+      ]
+    )
+  ]
+
+pinyin_cardinals ∷ (Integral i) ⇒ TestData i
+pinyin_cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (0, "líng")
+      , (1, "yī")
+      , (2, "èr")
+      , (3, "sān")
+      , (4, "sì")
+      , (5, "wǔ")
+      , (6, "liù")
+      , (7, "qī")
+      , (8, "bā")
+      , (9, "jiǔ")
+      , (10, "shí")
+      , (11, "shíyī")
+      , (12, "shíèr")
+      , (13, "shísān")
+      , (14, "shísì")
+      , (15, "shíwǔ")
+      , (16, "shíliù")
+      , (17, "shíqī")
+      , (18, "shíbā")
+      , (19, "shíjiǔ")
+      , (20, "èrshí")
+      , (21, "èrshí yī")
+      , (22, "èrshí èr")
+      , (23, "èrshí sān")
+      , (24, "èrshí sì")
+      , (25, "èrshí wǔ")
+      , (26, "èrshí liù")
+      , (27, "èrshí qī")
+      , (28, "èrshí bā")
+      , (29, "èrshí jiǔ")
+      , (30, "sānshí")
+      , (31, "sānshí yī")
+      , (32, "sānshí èr")
+      , (33, "sānshí sān")
+      , (34, "sānshí sì")
+      , (35, "sānshí wǔ")
+      , (36, "sānshí liù")
+      , (37, "sānshí qī")
+      , (38, "sānshí bā")
+      , (39, "sānshí jiǔ")
+      , (40, "sìshí")
+      , (41, "sìshí yī")
+      , (42, "sìshí èr")
+      , (43, "sìshí sān")
+      , (44, "sìshí sì")
+      , (45, "sìshí wǔ")
+      , (46, "sìshí liù")
+      , (47, "sìshí qī")
+      , (48, "sìshí bā")
+      , (49, "sìshí jiǔ")
+      , (50, "wǔshí")
+      , (51, "wǔshí yī")
+      , (52, "wǔshí èr")
+      , (53, "wǔshí sān")
+      , (54, "wǔshí sì")
+      , (55, "wǔshí wǔ")
+      , (56, "wǔshí liù")
+      , (57, "wǔshí qī")
+      , (58, "wǔshí bā")
+      , (59, "wǔshí jiǔ")
+      , (60, "liùshí")
+      , (61, "liùshí yī")
+      , (62, "liùshí èr")
+      , (63, "liùshí sān")
+      , (64, "liùshí sì")
+      , (65, "liùshí wǔ")
+      , (66, "liùshí liù")
+      , (67, "liùshí qī")
+      , (68, "liùshí bā")
+      , (69, "liùshí jiǔ")
+      , (70, "qīshí")
+      , (71, "qīshí yī")
+      , (72, "qīshí èr")
+      , (73, "qīshí sān")
+      , (74, "qīshí sì")
+      , (75, "qīshí wǔ")
+      , (76, "qīshí liù")
+      , (77, "qīshí qī")
+      , (78, "qīshí bā")
+      , (79, "qīshí jiǔ")
+      , (80, "bāshí")
+      , (81, "bāshí yī")
+      , (82, "bāshí èr")
+      , (83, "bāshí sān")
+      , (84, "bāshí sì")
+      , (85, "bāshí wǔ")
+      , (86, "bāshí liù")
+      , (87, "bāshí qī")
+      , (88, "bāshí bā")
+      , (89, "bāshí jiǔ")
+      , (90, "jiǔshí")
+      , (91, "jiǔshí yī")
+      , (92, "jiǔshí èr")
+      , (93, "jiǔshí sān")
+      , (94, "jiǔshí sì")
+      , (95, "jiǔshí wǔ")
+      , (96, "jiǔshí liù")
+      , (97, "jiǔshí qī")
+      , (98, "jiǔshí bā")
+      , (99, "jiǔshí jiǔ")
+      , (100, "yībǎi")
+      , (208, "èrbǎi líng bā")
+      , (280, "èrbǎi bāshí")
+      , (1000, "yīqiān")
+      , (1002, "yīqiān líng èr")
+      , (1020, "yīqiān líng èrshí")
+      , (1200, "yīqiān èrbǎi")
+      , (1203, "yīqiān èrbǎi líng sān")
+      , (1230, "yīqiān èrbǎi sānshí")
+      , (1234, "yīqiān èrbǎi sānshí sì")
+      , (2008, "liǎngqiān líng bā")
+      , (2080, "liǎngqiān líng bāshí")
+      , (2800, "liǎngqiān bābǎi")
+      , (97375, "jiǔwàn qīqiān sānbǎi qīshí wǔ")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Language/ZPC/TestData.hs b/src-test/Text/Numeral/Language/ZPC/TestData.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Language/ZPC/TestData.hs
@@ -0,0 +1,167 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        zpc
+
+[@Native name@]     -
+
+[@English name@]    Choapan Zapotec
+-}
+module Text.Numeral.Language.ZPC.TestData (cardinals) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Num )
+import "numerals" Text.Numeral.Grammar.Reified ( defaultInflection )
+import "this" Text.Numeral.Test ( TestData )
+
+
+--------------------------------------------------------------------------------
+-- Test data
+--------------------------------------------------------------------------------
+
+{-
+Sources:
+  http://www.languagesandnumbers.com/how-to-count-in-choapan-zapotec/en/zpc/
+-}
+
+cardinals ∷ (Num i) ⇒ TestData i
+cardinals =
+  [ ( "default"
+    , defaultInflection
+    , [ (1, "tu")
+      , (2, "chopa")
+      , (3, "tzona")
+      , (4, "tapa")
+      , (5, "ga’yo’")
+      , (6, "xopa")
+      , (7, "gadyi")
+      , (8, "xuna’")
+      , (9, "ga")
+      , (10, "chi")
+      , (11, "chiptu")
+      , (12, "chipchopa")
+      , (13, "chi’nnu")
+      , (14, "chi’da’")
+      , (15, "chi’no’")
+      , (16, "chi’no’ be tu")
+      , (17, "chi’no’ be chopa")
+      , (18, "chi’no be tzona")
+      , (19, "tu galo")
+      , (20, "galo")
+      , (21, "galo be tu")
+      , (22, "galo be chopa")
+      , (23, "galo be tzona")
+      , (24, "galo be tapa")
+      , (25, "galo be ga’yo’")
+      , (26, "galo be xopa")
+      , (27, "galo be gadyi")
+      , (28, "galo be xuna’")
+      , (29, "galo be ga")
+      , (30, "galo be chi")
+      , (31, "galo be chi tu")
+      , (32, "galo be chi chopa")
+      , (33, "galo be chi tzona")
+      , (34, "galo be chi tapa")
+      , (35, "galo be chi ga’yo’")
+      , (36, "galo be chi xopa")
+      , (37, "galo be chi gadyi")
+      , (38, "galo be chi xuna’")
+      , (39, "galo be chi ga")
+      , (40, "chopa galo")
+      , (41, "chopa galo tu")
+      , (42, "chopa galo chopa")
+      , (43, "chopa galo tzona")
+      , (44, "chopa galo tapa")
+      , (45, "chopa galo ga’yo’")
+      , (46, "chopa galo xopa")
+      , (47, "chopa galo gadyi")
+      , (48, "chopa galo xuna’")
+      , (49, "chopa galo ga")
+      , (50, "chopa galo chi")
+      , (51, "chopa galo chi tu")
+      , (52, "chopa galo chi chopa")
+      , (53, "chopa galo chi tzona")
+      , (54, "chopa galo chi tapa")
+      , (55, "chopa galo chi ga’yo’")
+      , (56, "chopa galo chi xopa")
+      , (57, "chopa galo chi gadyi")
+      , (58, "chopa galo chi xuna’")
+      , (59, "chopa galo chi ga")
+      , (60, "tzona galo")
+      , (61, "tzona galo tu")
+      , (62, "tzona galo chopa")
+      , (63, "tzona galo tzona")
+      , (64, "tzona galo tapa")
+      , (65, "tzona galo ga’yo’")
+      , (66, "tzona galo xopa")
+      , (67, "tzona galo gadyi")
+      , (68, "tzona galo xuna’")
+      , (69, "tzona galo ga")
+      , (70, "tzona galo chi")
+      , (71, "tzona galo chi tu")
+      , (72, "tzona galo chi chopa")
+      , (73, "tzona galo chi tzona")
+      , (74, "tzona galo chi tapa")
+      , (75, "tzona galo chi ga’yo’")
+      , (76, "tzona galo chi xopa")
+      , (77, "tzona galo chi gadyi")
+      , (78, "tzona galo chi xuna’")
+      , (79, "tzona galo chi ga")
+      , (80, "tapa galo")
+      , (81, "tapa galo tu")
+      , (82, "tapa galo chopa")
+      , (83, "tapa galo tzona")
+      , (84, "tapa galo tapa")
+      , (85, "tapa galo ga’yo’")
+      , (86, "tapa galo xopa")
+      , (87, "tapa galo gadyi")
+      , (88, "tapa galo xuna’")
+      , (89, "tapa galo ga")
+      , (90, "tapa galo chi")
+      , (91, "tapa galo chi tu")
+      , (92, "tapa galo chi chopa")
+      , (93, "tapa galo chi tzona")
+      , (94, "tapa galo chi tapa")
+      , (95, "tapa galo chi ga’yo’")
+      , (96, "tapa galo chi xopa")
+      , (97, "tapa galo chi gadyi")
+      , (98, "tapa galo chi xuna’")
+      , (99, "tapa galo chi ga")
+      , (100, "tu gayua")
+      , (101, "tu gayua tu")
+      , (102, "tu gayua chopa")
+      , (103, "tu gayua tzona")
+      , (104, "tu gayua tapa")
+      , (105, "tu gayua ga’yo’")
+      , (106, "tu gayua xopa")
+      , (107, "tu gayua gadyi")
+      , (108, "tu gayua xuna’")
+      , (109, "tu gayua ga")
+      , (110, "tu gayua chi")
+      , (123, "tu gayua galo be tzona")
+      , (200, "chopa gayua")
+      , (300, "tzona gayua")
+      , (321, "tzona gayua galo be tu")
+      , (400, "tapa gayua")
+      , (500, "ga’yo’ gayua")
+      , (600, "xopa gayua")
+      , (700, "gadyi gayua")
+      , (800, "xuna’ gayua")
+      , (900, "ga gayua")
+      , (909, "ga gayua ga")
+      , (990, "ga gayua tapa galo chi")
+      , (999, "ga gayua tapa galo chi ga")
+      ]
+    )
+  ]
diff --git a/src-test/Text/Numeral/Test.hs b/src-test/Text/Numeral/Test.hs
new file mode 100644
--- /dev/null
+++ b/src-test/Text/Numeral/Test.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+module Text.Numeral.Test ( TestData ) where
+
+import "base" Data.String ( String )
+import "numerals" Text.Numeral.Grammar.Reified ( Inflection )
+import "text" Data.Text ( Text )
+
+type TestData n = [(String, Inflection, [(n, Text)])]
diff --git a/src-test/test.hs b/src-test/test.hs
new file mode 100644
--- /dev/null
+++ b/src-test/test.hs
@@ -0,0 +1,675 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+
+module Main where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Control.Monad      ( (=<<), when )
+import "base" Data.Bool          ( Bool(True) )
+import "base" Data.Function      ( ($), on )
+import "base" Data.List          ( filter, groupBy, head, intercalate, length, map, sortBy )
+import "base" Data.Maybe         ( Maybe(Just), fromMaybe )
+import "base" Data.Ord           ( (<), (>), compare )
+import "base" Data.Tuple         ( fst, snd )
+import "base" Prelude            ( (+), (-), String )
+import "base" System.Environment ( getArgs )
+import "base" System.IO          ( IO )
+import "base" Text.Printf        ( printf )
+import "base" Text.Show          ( Show, show )
+import "base-unicode-symbols" Data.Eq.Unicode       ( (≡), (≢) )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Prelude.Unicode       ( ℤ, (⋅) )
+import "HUnit" Test.HUnit ( Assertion, assertFailure, assertBool )
+import           "numerals" Text.Numeral.Grammar
+import qualified "numerals" Text.Numeral.Grammar.Reified as GR
+import           "numerals" Text.Numeral.Misc ( dec, intLog )
+import "QuickCheck" Test.QuickCheck.Modifiers
+    ( Positive(Positive), NonNegative(NonNegative) )
+import "test-framework" Test.Framework ( defaultMainWithOpts
+                                       , interpretArgsOrExit
+                                       , ropt_hide_successes
+                                       , Test, testGroup
+                                       )
+import "test-framework-hunit" Test.Framework.Providers.HUnit ( testCase )
+import "test-framework-quickcheck2" Test.Framework.Providers.QuickCheck2 ( testProperty )
+import           "this" Text.Numeral.Test ( TestData )
+import "text" Data.Text ( Text )
+import qualified "text" Data.Text as T ( unpack )
+
+import qualified "numerals" Text.Numeral.Language.AF  as AF
+import qualified "numerals" Text.Numeral.Language.AMP as AMP
+import qualified "numerals" Text.Numeral.Language.BG  as BG
+import qualified "numerals" Text.Numeral.Language.CHN as CHN
+import qualified "numerals" Text.Numeral.Language.CHR as CHR
+import qualified "numerals" Text.Numeral.Language.CLM as CLM
+import qualified "numerals" Text.Numeral.Language.CS  as CS
+import qualified "numerals" Text.Numeral.Language.DE  as DE
+import qualified "numerals" Text.Numeral.Language.EN  as EN
+import qualified "numerals" Text.Numeral.Language.EO  as EO
+import qualified "numerals" Text.Numeral.Language.ES  as ES
+import qualified "numerals" Text.Numeral.Language.FI  as FI
+import qualified "numerals" Text.Numeral.Language.FR  as FR
+import qualified "numerals" Text.Numeral.Language.FUR as FUR
+import qualified "numerals" Text.Numeral.Language.GSW as GSW
+import qualified "numerals" Text.Numeral.Language.GV  as GV
+import qualified "numerals" Text.Numeral.Language.HE  as HE
+import qualified "numerals" Text.Numeral.Language.HOP as HOP
+import qualified "numerals" Text.Numeral.Language.IT  as IT
+import qualified "numerals" Text.Numeral.Language.JA  as JA
+import qualified "numerals" Text.Numeral.Language.LA  as LA
+import qualified "numerals" Text.Numeral.Language.LLD as LLD
+import qualified "numerals" Text.Numeral.Language.MG  as MG
+import qualified "numerals" Text.Numeral.Language.NL  as NL
+import qualified "numerals" Text.Numeral.Language.NO  as NO
+import qualified "numerals" Text.Numeral.Language.NQM as NQM
+import qualified "numerals" Text.Numeral.Language.OJ  as OJ
+import qualified "numerals" Text.Numeral.Language.PDC as PDC
+import qualified "numerals" Text.Numeral.Language.PL  as PL
+import qualified "numerals" Text.Numeral.Language.PT  as PT
+import qualified "numerals" Text.Numeral.Language.RU  as RU
+import qualified "numerals" Text.Numeral.Language.SCO as SCO
+import qualified "numerals" Text.Numeral.Language.SV  as SV
+import qualified "numerals" Text.Numeral.Language.TR  as TR
+import qualified "numerals" Text.Numeral.Language.WO  as WO
+import qualified "numerals" Text.Numeral.Language.YOR as YOR
+import qualified "numerals" Text.Numeral.Language.ZH  as ZH
+
+import qualified "this" Text.Numeral.Language.ACH.TestData as ACH
+import qualified "this" Text.Numeral.Language.ADY.TestData as ADY
+import qualified "this" Text.Numeral.Language.AF.TestData  as AF
+import qualified "this" Text.Numeral.Language.AMP.TestData as AMP
+import qualified "this" Text.Numeral.Language.ARI.TestData as ARI
+import qualified "this" Text.Numeral.Language.AST.TestData as AST
+import qualified "this" Text.Numeral.Language.AZ.TestData  as AZ
+import qualified "this" Text.Numeral.Language.BA.TestData  as BA
+import qualified "this" Text.Numeral.Language.BG.TestData  as BG
+import qualified "this" Text.Numeral.Language.BM.TestData  as BM
+import qualified "this" Text.Numeral.Language.CA.TestData  as CA
+import qualified "this" Text.Numeral.Language.CAF.TestData as CAF
+import qualified "this" Text.Numeral.Language.CBK.TestData as CBK
+import qualified "this" Text.Numeral.Language.CHN.TestData as CHN
+import qualified "this" Text.Numeral.Language.CHR.TestData as CHR
+import qualified "this" Text.Numeral.Language.CLM.TestData as CLM
+import qualified "this" Text.Numeral.Language.CO.TestData  as CO
+import qualified "this" Text.Numeral.Language.COD.TestData as COD
+import qualified "this" Text.Numeral.Language.COO.TestData as COO
+import qualified "this" Text.Numeral.Language.CS.TestData  as CS
+import qualified "this" Text.Numeral.Language.CY.TestData  as CY
+import qualified "this" Text.Numeral.Language.DE.TestData  as DE
+import qualified "this" Text.Numeral.Language.DJK.TestData as DJK
+import qualified "this" Text.Numeral.Language.EN.TestData  as EN
+import qualified "this" Text.Numeral.Language.EO.TestData  as EO
+import qualified "this" Text.Numeral.Language.ES.TestData  as ES
+import qualified "this" Text.Numeral.Language.ET.TestData  as ET
+import qualified "this" Text.Numeral.Language.FI.TestData  as FI
+import qualified "this" Text.Numeral.Language.FO.TestData  as FO
+import qualified "this" Text.Numeral.Language.FR.TestData  as FR
+import qualified "this" Text.Numeral.Language.FUR.TestData as FUR
+import qualified "this" Text.Numeral.Language.GCF_MTQ.TestData as GCF_MTQ
+import qualified "this" Text.Numeral.Language.GIL.TestData as GIL
+import qualified "this" Text.Numeral.Language.GL.TestData  as GL
+import qualified "this" Text.Numeral.Language.GSW.TestData as GSW
+import qualified "this" Text.Numeral.Language.GV.TestData  as GV
+import qualified "this" Text.Numeral.Language.HAI.TestData as HAI
+import qualified "this" Text.Numeral.Language.HE.TestData  as HE
+import qualified "this" Text.Numeral.Language.HOP.TestData as HOP
+import qualified "this" Text.Numeral.Language.HR.TestData  as HR
+import qualified "this" Text.Numeral.Language.HU.TestData  as HU
+import qualified "this" Text.Numeral.Language.HY.TestData  as HY
+import qualified "this" Text.Numeral.Language.IT.TestData  as IT
+import qualified "this" Text.Numeral.Language.JA.TestData  as JA
+import qualified "this" Text.Numeral.Language.KAP.TestData as KAP
+import qualified "this" Text.Numeral.Language.KEA.TestData as KEA
+import qualified "this" Text.Numeral.Language.LA.TestData  as LA
+import qualified "this" Text.Numeral.Language.LLD.TestData as LLD
+import qualified "this" Text.Numeral.Language.MG.TestData  as MG
+import qualified "this" Text.Numeral.Language.MOH.TestData as MOH
+import qualified "this" Text.Numeral.Language.NL.TestData  as NL
+import qualified "this" Text.Numeral.Language.NO.TestData  as NO
+import qualified "this" Text.Numeral.Language.NQM.TestData as NQM
+import qualified "this" Text.Numeral.Language.OJ.TestData  as OJ
+import qualified "this" Text.Numeral.Language.PAA.TestData as PAA
+import qualified "this" Text.Numeral.Language.PDC.TestData as PDC
+import qualified "this" Text.Numeral.Language.PL.TestData  as PL
+import qualified "this" Text.Numeral.Language.PT.TestData  as PT
+import qualified "this" Text.Numeral.Language.RMN_DZA.TestData as RMN_DZA
+import qualified "this" Text.Numeral.Language.RO.TestData  as RO
+import qualified "this" Text.Numeral.Language.RU.TestData  as RU
+import qualified "this" Text.Numeral.Language.SCO.TestData as SCO
+import qualified "this" Text.Numeral.Language.SV.TestData  as SV
+import qualified "this" Text.Numeral.Language.TAR.TestData as TAR
+import qualified "this" Text.Numeral.Language.TR.TestData  as TR
+import qualified "this" Text.Numeral.Language.WO.TestData  as WO
+import qualified "this" Text.Numeral.Language.YOR.TestData as YOR
+import qualified "this" Text.Numeral.Language.ZAQ.TestData as ZAQ
+import qualified "this" Text.Numeral.Language.ZH.TestData  as ZH
+import qualified "this" Text.Numeral.Language.ZPC.TestData as ZPC
+
+
+--------------------------------------------------------------------------------
+-- Test suite
+--------------------------------------------------------------------------------
+
+main ∷ IO ()
+main = do opts ← interpretArgsOrExit =<< getArgs
+          defaultMainWithOpts tests opts { ropt_hide_successes = Just True }
+
+tests ∷ [Test]
+tests =
+  [ testGroup "Grammar"
+    [ testGroup "Case"
+      [ testCase "noCase"       $ testInf noCase       hasNoCase
+      , testCase "nominative"   $ testInf nominative   isNominative
+      , testCase "accusative"   $ testInf accusative   isAccusative
+      , testCase "dative"       $ testInf dative       isDative
+      , testCase "ablative"     $ testInf ablative     isAblative
+      , testCase "genitive"     $ testInf genitive     isGenitive
+      , testCase "vocative"     $ testInf vocative     isVocative
+      , testCase "instrumental" $ testInf instrumental isInstrumental
+      ]
+    , testGroup "Gender"
+      [ testCase "noGender"  $ testInf noGender  hasNoGender
+      , testCase "neuter"    $ testInf neuter    isNeuter
+      , testCase "masculine" $ testInf masculine isMasculine
+      , testCase "feminine"  $ testInf feminine  isFeminine
+      , testCase "common"    $ testInf common    isCommon
+      ]
+    , testGroup "Number"
+      [ testCase "noNumber" $ testInf noNumber hasNoNumber
+      , testCase "singular" $ testInf singular isSingular
+      , testCase "dual"     $ testInf dual     isDual
+      , testCase "trial"    $ testInf trial    isTrial
+      , testCase "paucal"   $ testInf paucal   isPaucal
+      , testCase "plural"   $ testInf plural   isPlural
+      ]
+    ]
+  , testGroup "Misc"
+    [ testGroup "intLog"
+      [ testProperty "power of 10" intLog_pow10
+      , testProperty "power of 10 minus 1" intLog_pow10m1
+      , testProperty "multiply" intLog_mul
+      ]
+    ]
+  , testGroup "ACH"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (ACH.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "ADY"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (ADY.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "AF"
+    [ testGroup "unique data"
+      [ testUnique "cardinal" (AF.cardinals ∷ TestData ℤ)
+      , testUnique "ordinal"  (AF.ordinals  ∷ TestData ℤ)
+      ]
+    , mkTests "cardinal" AF.cardinal (AF.cardinals ∷ TestData ℤ)
+    , mkTests "ordinal"  AF.ordinal  (AF.ordinals  ∷ TestData ℤ)
+    ]
+  , testGroup "AMP"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (AMP.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" AMP.cardinal (AMP.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "ARI"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (ARI.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "AST"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (AST.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "AZ"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (AZ.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "BA"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (BA.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "BG"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (BG.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" BG.cardinal (BG.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "BM"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (BM.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "CA"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (CA.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "CAF"
+    [ testGroup "unique data"
+      [ testUnique "cardinal" (CAF.cardinals ∷ TestData ℤ)
+      , testUnique "cardinal (syllabic)" (CAF.syllabic_cardinals ∷ TestData ℤ)
+      ]
+    ]
+  , testGroup "CBK"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (CBK.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "CHN"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (CHN.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" CHN.cardinal (CHN.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "CHR"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (CHR.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" CHR.cardinal (CHR.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "CLM"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (CLM.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" CLM.cardinal (CLM.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "CO"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (CO.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "COD"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (COD.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "COO"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (COO.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "CS"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (CS.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" CS.cardinal (CS.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "CY"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (CY.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "DE"
+    [ testGroup "unique data"
+      [ testUnique "cardinal" (DE.cardinals ∷ TestData ℤ)
+      , testUnique "ordinal"  (DE.ordinals  ∷ TestData ℤ)
+      ]
+    , mkTests "cardinal" DE.cardinal (DE.cardinals ∷ TestData ℤ)
+    , mkTests "ordinal"  DE.ordinal  (DE.ordinals  ∷ TestData ℤ)
+    ]
+  , testGroup "DJK"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (DJK.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "EN"
+    [ testGroup "GB"
+      [ testGroup "unique data"
+        [ testUnique "cardinal" (EN.gb_cardinals ∷ TestData ℤ)
+        , testUnique "ordinal"  (EN.gb_ordinals  ∷ TestData ℤ)
+        ]
+      , mkTests "cardinal" EN.gb_cardinal (EN.gb_cardinals ∷ TestData ℤ)
+      , mkTests "ordinal"  EN.gb_ordinal  (EN.gb_ordinals  ∷ TestData ℤ)
+      ]
+    , testGroup "US"
+      [ testGroup "unique data"
+        [ testUnique "cardinal" (EN.us_cardinals ∷ TestData ℤ)
+        , testUnique "ordinal"  (EN.us_ordinals  ∷ TestData ℤ)
+        ]
+      , mkTests "cardinal" EN.us_cardinal (EN.us_cardinals ∷ TestData ℤ)
+      , mkTests "ordinal"  EN.us_ordinal  (EN.us_ordinals  ∷ TestData ℤ)
+      ]
+    ]
+  , testGroup "EO"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (EO.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" EO.cardinal (EO.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "ES"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (ES.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" ES.cardinal (ES.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "ET"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (ET.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "FI"
+    [ testGroup "unique data"
+      [ testUnique "cardinal" (FI.cardinals ∷ TestData ℤ)
+      , testUnique "ordinal"  (FI.ordinals  ∷ TestData ℤ)
+      ]
+    , mkTests "cardinal" FI.cardinal (FI.cardinals ∷ TestData ℤ)
+    , mkTests "ordinal"  FI.ordinal  (FI.ordinals ∷ TestData ℤ)
+    ]
+  , testGroup "FO"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (FO.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "FR"
+    [ testGroup "unique data"
+      [ testUnique "cardinal" (FR.cardinals ∷ TestData ℤ)
+      , testUnique "ordinal"  (FR.ordinals  ∷ TestData ℤ)
+      ]
+    , mkTests "cardinal" FR.cardinal (FR.cardinals ∷ TestData ℤ)
+    , mkTests "ordinal"  FR.ordinal  (FR.ordinals  ∷ TestData ℤ)
+    ]
+  , testGroup "FUR"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (FUR.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" FUR.cardinal (FUR.cardinals ∷ TestData ℤ)
+   ]
+  , testGroup "GCF_MTQ"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (GCF_MTQ.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "GIL"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (GIL.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "GL"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (GL.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "GSW"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (GSW.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" GSW.cardinal (GSW.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "GV"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (GV.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" GV.cardinal  (GV.cardinals  ∷ TestData ℤ)
+    ]
+  , testGroup "HAI"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (HAI.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "HE"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (HE.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" HE.cardinal  (HE.cardinals  ∷ TestData ℤ)
+    ]
+  , testGroup "HOP"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (HOP.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" HOP.cardinal (HOP.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "HR"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (HR.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "HU"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (HU.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "HY"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (HY.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "IT"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (IT.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" IT.cardinal (IT.cardinals ∷ TestData ℤ)
+    , mkTests "ordinal"  IT.ordinal  (IT.ordinals  ∷ TestData ℤ)
+    ]
+  , testGroup "JA"
+    [ testGroup "preferred"
+      [ testGroup "unique data"
+        [testUnique "cardinal" (JA.preferred_cardinals ∷ TestData ℤ)]
+      , mkTests "cardinal" JA.preferred_cardinal
+                          (JA.preferred_cardinals ∷ TestData ℤ)
+      ]
+    , testGroup "kanji"
+      [ testGroup "unique data"
+        [testUnique "cardinal" (JA.kanji_cardinals ∷ TestData ℤ)]
+      , mkTests "cardinal" JA.kanji_cardinal (JA.kanji_cardinals ∷ TestData ℤ)
+      ]
+    , testGroup "daiji"
+      [ testGroup "unique data"
+        [testUnique "cardinal" (JA.daiji_cardinals ∷ TestData ℤ)]
+      , mkTests "cardinal" JA.daiji_cardinal (JA.daiji_cardinals ∷ TestData ℤ)
+      ]
+    ]
+  , testGroup "KAP"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (KAP.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "KEA"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (KEA.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "LA"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (LA.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" LA.cardinal (LA.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "LLD"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (LLD.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" LLD.cardinal (LLD.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "MG"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (MG.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" MG.cardinal (MG.cardinals  ∷ TestData ℤ)
+    ]
+  , testGroup "MOH"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (MOH.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "NL"
+    [ testGroup "unique data"
+      [ testUnique "cardinal"       (NL.cardinals       ∷ TestData ℤ)
+      , testUnique "ordinal"        (NL.ordinals        ∷ TestData ℤ)
+      , testUnique "partitive"      (NL.partitives      ∷ TestData (ℤ, ℤ))
+      , testUnique "multiplicative" (NL.multiplicatives ∷ TestData ℤ)
+      ]
+    , mkTests "cardinal"       NL.cardinal  (NL.cardinals  ∷ TestData ℤ)
+    , mkTests "ordinal"        NL.ordinal   (NL.ordinals   ∷ TestData ℤ)
+    , mkTests "partitive"      NL.partitive (NL.partitives ∷ TestData (ℤ, ℤ))
+    , mkTests "multiplicative" NL.multiplicative (NL.multiplicatives ∷ TestData ℤ)
+    ]
+  , testGroup "NO"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (NO.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" NO.cardinal  (NO.cardinals  ∷ TestData ℤ)
+    ]
+  , testGroup "NQM"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (NQM.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" NQM.cardinal (NQM.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "OJ"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (OJ.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" OJ.cardinal  (OJ.cardinals  ∷ TestData ℤ)
+    ]
+  , testGroup "PAA"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (PAA.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "PDC"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (PDC.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" PDC.cardinal (PDC.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "PL"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (PL.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" PL.cardinal  (PL.cardinals  ∷ TestData ℤ)
+    ]
+  , testGroup "PT"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (PT.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" PT.cardinal (PT.cardinals  ∷ TestData ℤ)
+    , mkTests "ordinal"  PT.ordinal  (PT.ordinals   ∷ TestData ℤ)
+    ]
+  , testGroup "RMN_DZA"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (RMN_DZA.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "RO"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (RO.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "RU"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (RU.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" RU.cardinal  (RU.cardinals  ∷ TestData ℤ)
+    ]
+  , testGroup "SCO"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (SCO.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" SCO.cardinal (SCO.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "SV"
+    [ testGroup "unique data"
+      [ testUnique "cardinal" (SV.cardinals ∷ TestData ℤ)
+      , testUnique "ordinal"  (SV.ordinals  ∷ TestData ℤ)
+      ]
+    , mkTests "cardinal" SV.cardinal (SV.cardinals ∷ TestData ℤ)
+    , mkTests "ordinal"  SV.ordinal  (SV.ordinals  ∷ TestData ℤ)
+    ]
+  , testGroup "TAR"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (TAR.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "TR"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (TR.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" TR.cardinal (TR.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "WO"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (WO.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" WO.cardinal (WO.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "YOR"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (YOR.cardinals ∷ TestData ℤ)]
+    , mkTests "cardinal" YOR.cardinal (YOR.cardinals ∷ TestData ℤ)
+    ]
+  , testGroup "ZAQ"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (ZAQ.cardinals ∷ TestData ℤ)]
+    ]
+  , testGroup "ZH"
+    [ testGroup "characters (traditional)"
+      [ testGroup "unique data"
+        [testUnique "cardinal" (ZH.trad_cardinals ∷ TestData ℤ)]
+      , mkTests "cardinal" ZH.trad_cardinal (ZH.trad_cardinals ∷ TestData ℤ)
+      ]
+    , testGroup "characters (simplified)"
+      [ testGroup "unique data"
+        [testUnique "cardinal" (ZH.simpl_cardinals ∷ TestData ℤ)]
+      , mkTests "cardinal" ZH.simpl_cardinal (ZH.simpl_cardinals ∷ TestData ℤ)
+      ]
+    , testGroup "financial characters (traditional)"
+      [ testGroup "unique data"
+        [testUnique "cardinal" (ZH.finance_trad_cardinals ∷ TestData ℤ)]
+      , mkTests "cardinal" ZH.finance_trad_cardinal (ZH.finance_trad_cardinals ∷ TestData ℤ)
+      ]
+    , testGroup "financial characters (simplified)"
+      [ testGroup "unique data"
+        [testUnique "cardinal" (ZH.finance_simpl_cardinals ∷ TestData ℤ)]
+      , mkTests "cardinal" ZH.finance_simpl_cardinal (ZH.finance_simpl_cardinals ∷ TestData ℤ)
+      ]
+    , testGroup "pinyin"
+      [ testGroup "unique data"
+        [testUnique "cardinal" (ZH.pinyin_cardinals ∷ TestData ℤ)]
+      , mkTests "cardinal" ZH.pinyin_cardinal (ZH.pinyin_cardinals ∷ TestData ℤ)
+      ]
+  , testGroup "ZPC"
+    [ testGroup "unique data"
+      [testUnique "cardinal" (ZPC.cardinals ∷ TestData ℤ)]
+    ]
+    ]
+  ]
+
+
+--------------------------------------------------------------------------------
+-- Utils
+--------------------------------------------------------------------------------
+
+{-
+-- TODO: this takes way to long for large values (10 ^ 60000 - 1)
+testBounds ∷ Text → (ℤ → Maybe Text) → (ℤ, ℤ) → Test
+testBounds name conversion bounds@(lo, hi) =
+      testGroup name
+                [ testCase "lower bound" $ assertBool "conversion error" $ checkConv lo
+                , testCase "upper bound" $ assertBool "conversion error" $ checkConv hi
+                -- , testProperty "in between" $ forAll (choose bounds) checkConv
+                ]
+    where
+      checkConv ∷ ℤ → Bool
+      checkConv = isJust ∘ conversion
+-}
+
+testInf ∷ (GR.Inflection → GR.Inflection) → (GR.Inflection → Bool) → Assertion
+testInf set test = assertBool "False" $ test $ set GR.defaultInflection
+
+intLog_pow10 ∷ Positive ℤ → Bool
+intLog_pow10 (Positive x) = x ≡ intLog (dec x)
+
+intLog_pow10m1 ∷ NonNegative ℤ → Bool
+intLog_pow10m1 (NonNegative x) = x - 1 ≡ intLog (dec x) - 1
+
+intLog_mul ∷ Positive ℤ → Positive ℤ → Bool
+intLog_mul (Positive x) (Positive y) = intLog (dec x ⋅ dec y) ≡ intLog (dec x) + intLog (dec y)
+
+mkTests ∷ ∀ α. (Show α)
+        ⇒ String
+        → (GR.Inflection → α → Maybe Text)
+        → TestData α
+        → Test
+mkTests name f = testGroup name ∘ map perInflection
+  where
+    perInflection ∷ (String, GR.Inflection, [(α, Text)]) → Test
+    perInflection (infName, inf, xs) = testGroup infName $ map (perValue inf) xs
+
+    perValue ∷ GR.Inflection → (α, Text) → Test
+    perValue inf (n, s) = testCase (show n) $ testConversion f inf n s
+
+-- | Tests whether the test data contains duplicates (different
+-- numbers with the same representation).
+testUnique ∷ ∀ α. (Show α) ⇒ String → TestData α → Test
+testUnique name = testGroup name ∘ map perInflection
+  where
+    perInflection ∷ (String, inf, [(α, Text)]) → Test
+    perInflection (infName, _, xs) = testCase infName $ unique xs
+
+    unique ∷ [(α, Text)] → Assertion
+    unique xs = when (length ys > 0)
+                  $ assertFailure
+                  $ intercalate "\n" $ map msg ys
+      where
+        ys ∷ [[(α, Text)]]
+        ys = filter ((1 <) ∘ length)
+             $ groupBy ((≡) `on` snd)
+             $ sortBy (compare `on` snd) xs
+
+    msg ∷ [(α, Text)] → String
+    msg xs = let (_, s) = head xs
+             in printf "The string \"%s\" is associated with multiple values: %s"
+                       (T.unpack s)
+                       (intercalate ", " $ map (show ∘ fst) xs)
+
+testConversion ∷ (Show α)
+               ⇒ (GR.Inflection → α → Maybe Text)
+               → GR.Inflection
+               → α
+               → Text
+               → Assertion
+testConversion f inf n s =
+  let r = f inf n
+  in when (r ≢ Just s)
+        $ assertFailure
+        $ printf "Expected %s = \"%s\" but got \"%s\""
+                 (show n)
+                 (T.unpack s)
+                 (T.unpack $ fromMaybe "no result" r)
diff --git a/src/Text/Numeral.hs b/src/Text/Numeral.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral.hs
@@ -0,0 +1,72 @@
+{-# LANGUAGE PackageImports #-}
+
+module Text.Numeral
+    ( -- * Overview
+      -- $overview
+
+      -- ** Expression language
+      -- $dsl
+
+      -- ** Rules
+      -- $rules
+
+      -- ** Rendering
+      -- $render
+
+      module Text.Numeral.Exp.Reified
+    , module Text.Numeral.Render
+    , module Text.Numeral.Rules
+    )
+    where
+
+-------------------------------------------------------------------------------
+-- Imports
+-------------------------------------------------------------------------------
+
+import "this" Text.Numeral.Exp.Reified
+import "this" Text.Numeral.Render
+import "this" Text.Numeral.Rules
+
+-------------------------------------------------------------------------------
+-- Documentation
+-------------------------------------------------------------------------------
+
+{- $overview
+
+The general idea behind this package is to take a number, convert that
+number to an abstract representation of its spoken form and finally
+render that representation to a 'Text' value.
+
+-}
+
+{- $dsl
+
+Numerals are represented by a small expression language defined in the
+"Text.Numeral.Exp" module. This language is also reified as the
+concrete type 'Exp' in the "Text.Numeral.Exp.Reified" module.
+
+-}
+
+{- $rules
+
+Conversion from numbers to numerals is the responsibility of
+rules. The 'Rule' type itself and a number of useful rules are defined
+in the "Text.Numeral.Rules" module. All rules are completely
+polymorphic in their types. Their result types are only constrained by
+the type classes that make up the numeral expression language.
+
+-}
+
+{- $render
+
+Finally, the "Text.Numeral.Render" module is responsible for
+converting the numeral expression language to a 'Text' value. This
+happens via the 'render' function. Render is parametrised with a
+'Repr' value and with an 'Inflection'. The 'Repr' contains all the
+knowledge on how to convert the abstract expression to a concrete
+'Text' value. The 'Inflection' is used for languages where number
+words change based on a number of grammatical categories such as case,
+gender or number. The expression itself is passed as a concrete 'Exp'
+value.
+
+-}
diff --git a/src/Text/Numeral/BigNum.hs b/src/Text/Numeral/BigNum.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/BigNum.hs
@@ -0,0 +1,153 @@
+{-# LANGUAGE NoImplicitPrelude
+           , OverloadedStrings
+           , PackageImports
+           , UnicodeSyntax
+  #-}
+
+module Text.Numeral.BigNum
+  ( cardinal
+  , rule
+  , cardinalRepr
+  , symMap
+  , forms
+
+  , PostfixRepr
+  , scaleRepr
+  , pelletierRepr
+
+  , quantityName
+  , ordQuantityName
+  ) where
+
+
+-------------------------------------------------------------------------------
+-- Imports
+-------------------------------------------------------------------------------
+
+import "base" Data.Bool     ( otherwise )
+import "base" Data.Function ( ($), const, fix )
+import "base" Data.Functor  ( (<$>) )
+import "base" Data.Maybe    ( Maybe(Nothing, Just) )
+import "base" Prelude       ( Integral, (-) )
+import "base-unicode-symbols"       Data.Eq.Unicode       ( (≡) )
+import "base-unicode-symbols"       Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols"       Data.List.Unicode     ( (∈) )
+import "base-unicode-symbols"       Data.Monoid.Unicode   ( (⊕) )
+import "base-unicode-symbols"       Prelude.Unicode       ( ℤ )
+import "containers-unicode-symbols" Data.Map.Unicode      ( (∪) )
+import "this"                       Text.Numeral
+import "this"                       Text.Numeral.Misc     ( dec )
+import qualified "containers" Data.Map as M ( Map, fromList, lookup )
+import qualified "this"       Text.Numeral.Exp as E
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- Language of Big Numbers
+--------------------------------------------------------------------------------
+
+cardinal ∷ (Integral α) ⇒ inf → α → Maybe Text
+cardinal inf = render cardinalRepr inf ∘ (pos $ fix rule)
+
+rule ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ Rule α β
+rule = findRule (   1, lit         )
+              [ (  11, add   10 L  )
+              , (  20, mul   10 L L)
+              , ( 100, lit         )
+              , ( 101, add  100 L  )
+              , ( 200, mul  100 R L)
+              , (1000, lit         )
+              , (1001, add 1000 L  )
+              , (2000, mul 1000 R L)
+              ]
+                (dec 4 - 1)
+
+cardinalRepr ∷ Repr inf
+cardinalRepr =
+    defaultRepr { reprValue = \_ n → M.lookup n symMap
+                , reprAdd   = Just $ \_ _ _ → ""
+                , reprMul   = Just $ \_ _ _ → ""
+                }
+
+symMap ∷ (Integral α) ⇒ M.Map α (Ctx (Exp i) → Text)
+symMap = M.fromList
+         [ (1, forms "m"     "un"       "un"       ""        "")
+         , (2, forms "b"     "duo"      "duo"      "vi"      "du")
+         , (3, forms "tr"    "tre"      "tres"     "tri"     "tre")
+         , (4, forms "quadr" "quattuor" "quattuor" "quadra"  "quadri")
+         , (5, forms "quint" "quin"     "quinqua"  "quinqua" "quin")
+         , (6, forms "sext"  "sex"      "ses"      "sexa"    "ses")
+         , (7, forms "sept"  "septen"   "septem"   "septua"  "septin")
+         , (8, forms "oct"   "octo"     "octo"     "octo"    "octin")
+         , (9, forms "non"   "novem"    "novem"    "nona"    "non")
+         , (10, \c → case c of
+                       CtxAdd _ (Lit 100) _              → "deci"
+                       CtxMul _ _ (CtxAdd L (Lit 100) _) → "ginta"
+                       CtxMul {}                         → "gint"
+                       _                                 → "dec"
+           )
+         , (100, \c → case c of
+                        CtxMul _ (Lit n) _
+                            | n ∈ [2,3,6] → "cent"
+                            | otherwise   → "gent"
+                        _                 → "cent"
+           )
+         , (1000, const "millin")
+         ]
+
+forms ∷ Text → Text → Text → Text → Text → Ctx (Exp i) → Text
+forms t a1 a2 m1 m2 ctx =
+    case ctx of
+      CtxAdd _ (Lit 10)  _ → a1
+      CtxAdd {}            → a2
+      CtxMul _ (Lit 10)  _ → m1
+      CtxMul {}            → m2
+      _                    → t
+
+
+--------------------------------------------------------------------------------
+-- Representations of scales
+--------------------------------------------------------------------------------
+
+-- | Function that renders the postfix part of a large number name. Or
+-- more simply put, this calculates the \"illion\" part of
+-- \"million\", \"billion\", etc.
+type PostfixRepr i = i           -- ^ Current inflection.
+                   → Ctx (Exp i) -- ^ Context.
+                   → Text        -- ^ Postfix representation.
+
+scaleRepr ∷ PostfixRepr i
+          → [(ℤ, Ctx (Exp i) → Text)] -- ^ Additional symbol map entries.
+          → ScaleRepr i
+scaleRepr pf syms inf _ _ e ctx = (⊕ pf inf ctx) <$> render repr inf e
+    where
+      repr = cardinalRepr { reprValue = \_ n → M.lookup n syms' }
+      syms' = M.fromList syms ∪ symMap
+
+pelletierRepr ∷ PostfixRepr i -- ^Postfix for offset 0 names.
+              → PostfixRepr i -- ^Postfix for offset 3 names.
+              → [(ℤ, Ctx (Exp i) → Text)] -- ^ Additional symbol map entries.
+              → ScaleRepr i
+pelletierRepr pf0 pf3 syms inf
+              b o e ctx | o ≡ 0 = scaleRepr pf0 syms inf b o e ctx
+                        | o ≡ 3 = scaleRepr pf3 syms inf b o e ctx
+                        | otherwise = Nothing
+
+quantityName ∷ Text → Text → PostfixRepr i
+quantityName s p _ ctx =
+    case ctx of
+      CtxMul _ (Lit 1) _ → s
+      CtxMul {}          → p
+      _                  → s
+
+ordQuantityName ∷ Text → Text → Text → Text → PostfixRepr i
+ordQuantityName sc so pc po _ ctx =
+    case ctx of
+      CtxMul _ (Lit 1) _ | outside   → so
+                         | otherwise → sc
+      CtxMul {}          | outside   → po
+                         | otherwise → pc
+      _                  | outside   → so
+                         | otherwise → sc
+    where
+      outside = isOutside R ctx
diff --git a/src/Text/Numeral/Entry.hs b/src/Text/Numeral/Entry.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Entry.hs
@@ -0,0 +1,56 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+module Text.Numeral.Entry
+    ( Conversion(..)
+    , Entry(..)
+    , emptyEntry
+    ) where
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Data.Maybe  ( Maybe(Nothing) )
+import "base-unicode-symbols" Prelude.Unicode ( ℤ )
+import "this" Text.Numeral.Exp.Reified ( Exp )
+import "this" Text.Numeral.Grammar.Reified ( Inflection )
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- Language entry
+--------------------------------------------------------------------------------
+
+data Conversion α = Conversion
+    { toNumeral   ∷ Inflection → α → Maybe Text
+    , toStructure ∷ α → Exp Inflection
+    }
+
+data Entry = Entry
+    { entIso639_1       ∷ Maybe Text
+    , entIso639_2       ∷ [Text]
+    , entIso639_3       ∷ Maybe Text
+    , entNativeNames    ∷ [Text]
+    , entEnglishName    ∷ Maybe Text
+    , entVariant        ∷ Maybe Text
+    , entCardinal       ∷ Maybe (Conversion ℤ)
+    , entOrdinal        ∷ Maybe (Conversion ℤ)
+    , entPartitive      ∷ Maybe (Conversion (ℤ, ℤ))
+    , entMultiplicative ∷ Maybe (Conversion ℤ)
+    }
+
+emptyEntry ∷ Entry
+emptyEntry = Entry
+    { entIso639_1       = Nothing
+    , entIso639_2       = []
+    , entIso639_3       = Nothing
+    , entNativeNames    = []
+    , entEnglishName    = Nothing
+    , entVariant        = Nothing
+    , entCardinal       = Nothing
+    , entOrdinal        = Nothing
+    , entPartitive      = Nothing
+    , entMultiplicative = Nothing
+    }
diff --git a/src/Text/Numeral/Exp.hs b/src/Text/Numeral/Exp.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Exp.hs
@@ -0,0 +1,144 @@
+{-# LANGUAGE NoImplicitPrelude
+           , PackageImports
+           , TypeFamilies
+           , TypeSynonymInstances
+           , UnicodeSyntax
+  #-}
+
+module Text.Numeral.Exp
+    ( Unknown(unknown, isUnknown)
+    , Lit(lit)
+    , Neg(neg)
+    , Add(add)
+    , Mul(mul)
+    , Sub(sub)
+    , Frac(frac)
+    , Scale(scale)
+    , Dual(dual)
+    , Plural(plural)
+    , Inflection(..)
+    ) where
+
+-------------------------------------------------------------------------------
+-- Imports
+-------------------------------------------------------------------------------
+
+import "base" Data.Bool ( Bool(False) )
+import "base" Data.Function ( const )
+import "base" Prelude ( (+), (*), (^), subtract, negate, fromInteger, error )
+import "base-unicode-symbols" Prelude.Unicode ( ℤ, (⋅) )
+
+
+-------------------------------------------------------------------------------
+-- Expressions
+-------------------------------------------------------------------------------
+
+-- | An unknown value. This is used to signal that a value can not be
+-- represented in the expression language.
+--
+-- Law: isUnknown unknown == True
+class Unknown α where
+    unknown ∷ α
+    isUnknown ∷ α → Bool
+
+-- | A literal value.
+--
+-- Example in English:
+--
+-- > "three" = lit 3
+class Lit α where lit ∷ ℤ → α
+
+-- | Negation of a value.
+--
+-- Example in English:
+--
+-- > "minus two" = neg (lit 2)
+class Neg α where neg ∷ α → α
+
+-- | Addition of two values.
+--
+-- Example in English:
+--
+-- > "fifteen" = lit 5 `add` lit 10
+class Add α where add ∷ α → α → α
+
+-- | Multiplication of two values.
+--
+-- Example in English:
+--
+-- > "thirty" = lit 3 `mul` lit 10
+class Mul α where mul ∷ α → α → α
+
+-- | One value subtracted from another value.
+--
+-- Example in Latin:
+--
+-- > "duodēvīgintī" = lit 2 `sub` (lit 2 `mul` lit 10)
+class Sub α where sub ∷ α → α → α
+
+-- | A fraction.
+--
+-- Example in English:
+--
+-- > "two thirds" = `frac` (lit 2) (lit 3)
+class Frac α where frac ∷ α → α → α
+
+-- | A step in a scale of large values.
+--
+-- Should be interpreted as @10 ^ (rank * base + offset)@.
+--
+-- Example in English:
+--
+-- > "quadrillion" = scale 3 3 4
+class Scale α where
+    scale ∷ ℤ -- ^ Base.
+          → ℤ -- ^ Offset.
+          → α -- ^ Rank.
+          → α
+
+-- | A dual of a value.
+--
+-- This is used in some languages that express some values as the dual
+-- of a smaller value. For instance, in Hebrew the number 20 is
+-- expressed as the dual of 10.
+class Dual α where dual ∷ α → α
+
+-- | A plural of a value.
+--
+-- This is used in some languages that express some values as the
+-- plural of a smaller value. For instance, in Hebrew the numbers
+-- [30,40..90] are expressed as the plurals of [3..9].
+class Plural α where plural ∷ α → α
+
+-- | A change of inflection.
+--
+-- This is used in a language like Spanish where the inflection of a
+-- number word is not always constant. Specifically, in Spanish, large
+-- number names always have the masculine gender. So 'millón',
+-- 'billón' and the like are all masculine. This can result in the
+-- following number word: 10000001 = "un (masculine) millón una
+-- (feminine)"
+class Inflection α where
+    type Inf α
+    inflection ∷ (Inf α → Inf α) → α → α
+
+infixl 6 `add`
+infixl 6 `sub`
+infixl 7 `mul`
+
+
+-------------------------------------------------------------------------------
+-- Integer instances
+-------------------------------------------------------------------------------
+
+instance Unknown ℤ where
+    unknown   = error "unknown"
+    isUnknown = const False
+instance Lit ℤ where lit = fromInteger
+instance Neg ℤ where neg = negate
+instance Add ℤ where add = (+)
+instance Mul ℤ where mul = (*)
+instance Sub ℤ where sub = subtract
+instance Scale ℤ where scale b o r = 10 ^ (r⋅b + o)
+
+-- TODO: instances for ℚ?
diff --git a/src/Text/Numeral/Exp/Reified.hs b/src/Text/Numeral/Exp/Reified.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Exp/Reified.hs
@@ -0,0 +1,111 @@
+{-# LANGUAGE CPP
+           , NoImplicitPrelude
+           , PackageImports
+           , TypeFamilies
+           , UnicodeSyntax
+  #-}
+
+module Text.Numeral.Exp.Reified ( Exp(..), showExp, Side(L, R) ) where
+
+
+-------------------------------------------------------------------------------
+-- Imports
+-------------------------------------------------------------------------------
+
+import "base" Data.Bool ( Bool(False, True) )
+import "base" Data.Eq   ( Eq )
+import "base" Data.List ( (++) )
+import "base" Prelude   ( String )
+import "base" Text.Show ( Show, show )
+import "base-unicode-symbols" Prelude.Unicode ( ℤ )
+import qualified "this" Text.Numeral.Exp as E
+
+
+-------------------------------------------------------------------------------
+-- Reified expression type
+-------------------------------------------------------------------------------
+
+-- | An expression that represents the structure of a numeral.
+data Exp i
+          -- | An unknown value.
+         = Unknown
+          -- | A literal value.
+         | Lit ℤ
+           -- | Negation of an expression.
+         | Neg (Exp i)
+           -- | Addition of two expressions.
+         | Add (Exp i) (Exp i)
+           -- | Multiplication of two expressions.
+         | Mul (Exp i) (Exp i)
+           -- | One expression subtracted from another expression.
+         | Sub (Exp i) (Exp i)
+           -- | A fraction.
+         | Frac (Exp i) (Exp i)
+           -- | A step in a scale of large values.
+         | Scale ℤ ℤ (Exp i)
+           -- | A dual form of an expression.
+         | Dual (Exp i)
+           -- | A plural form of an expression.
+         | Plural (Exp i)
+           -- | A change of inflection.
+         | Inflection (i → i) (Exp i)
+
+infixl 6 `Add`
+infixl 6 `Sub`
+infixl 7 `Mul`
+
+showExp ∷ Exp i → String
+showExp Unknown = "Unknown"
+showExp (Lit n) = "Lit " ++ show n
+showExp (Neg x) = "Neg (" ++ showExp x ++ ")"
+showExp (Add  x y) = "Add ("  ++ showExp x ++ ") (" ++ showExp y ++ ")"
+showExp (Mul  x y) = "Mul ("  ++ showExp x ++ ") (" ++ showExp y ++ ")"
+showExp (Sub  x y) = "Sub ("  ++ showExp x ++ ") (" ++ showExp y ++ ")"
+showExp (Frac x y) = "Frac (" ++ showExp x ++ ") (" ++ showExp y ++ ")"
+showExp (Scale b o r) = "Scale " ++ show b ++ " " ++ show o ++ " (" ++ showExp r ++ ")"
+showExp (Dual   x) = "Dual ("   ++ showExp x ++ ")"
+showExp (Plural x) = "Plural (" ++ showExp x ++ ")"
+showExp (Inflection _ x) = "Inflection <func> (" ++ showExp x ++ ")"
+
+
+-- | Precisely the 'Unknown' constructor.
+instance E.Unknown (Exp i) where
+    unknown = Unknown
+    isUnknown Unknown = True
+    isUnknown _       = False
+-- | Precisely the 'Lit' constructor.
+instance E.Lit (Exp i) where lit = Lit
+-- | Precisely the 'Neg' constructor.
+instance E.Neg (Exp i) where neg = Neg
+-- | Precisely the 'Add' constructor.
+instance E.Add (Exp i) where add = Add
+-- | Precisely the 'Mul' constructor.
+instance E.Mul (Exp i) where mul = Mul
+-- | Precisely the 'Sub' constructor.
+instance E.Sub (Exp i) where sub = Sub
+-- | Precisely the 'Frac' constructor.
+instance E.Frac (Exp i) where frac = Frac
+-- | Precisely the 'Scale' constructor.
+instance E.Scale (Exp i) where scale = Scale
+-- | Precisely the 'Dual' constructor.
+instance E.Dual (Exp i) where dual = Dual
+-- | Precisely the 'Plural' constructor.
+instance E.Plural (Exp i) where plural = Plural
+-- | Precisely the 'Inflection' constructor.
+instance E.Inflection (Exp i) where
+#if __GLASGOW_HASKELL__ < 704
+    type E.Inf (Exp i) = i
+#else
+    type Inf (Exp i) = i
+#endif
+    inflection = Inflection
+
+
+-------------------------------------------------------------------------------
+-- Side
+-------------------------------------------------------------------------------
+
+-- | A side or direction, either 'L'eft or 'R'ight.
+data Side = L -- ^ Left.
+          | R -- ^ Right.
+            deriving (Eq, Show)
diff --git a/src/Text/Numeral/Grammar.hs b/src/Text/Numeral/Grammar.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Grammar.hs
@@ -0,0 +1,329 @@
+{-# LANGUAGE NoImplicitPrelude
+           , UnicodeSyntax
+           , PackageImports
+  #-}
+
+module Text.Numeral.Grammar
+    ( -- * Inflection
+      Inflection
+      -- * Grammatical categories
+      -- ** Case
+    , NoCase               (noCase,               hasNoCase)
+    , Ablative             (ablative,             isAblative)
+    , Abessive             (abessive,             isAbessive)
+    , Accusative           (accusative,           isAccusative)
+    , Comitative           (comitative,           isComitative)
+    , Dative               (dative,               isDative)
+    , Delative             (delative,             isDelative)
+    , Distributive         (distributive,         isDistributive)
+    , DistributiveTemporal (distributiveTemporal, isDistributiveTemporal)
+    , Essive               (essive,               isEssive)
+    , Genitive             (genitive,             isGenitive)
+    , Instrumental         (instrumental,         isInstrumental)
+    , Instructive          (instructive,          isInstructive)
+    , Lative               (lative,               isLative)
+    , Locative             (locative,             isLocative)
+    , Multiplicative       (multiplicative,       isMultiplicative)
+    , Nominative           (nominative,           isNominative)
+    , Partitive            (partitive,            isPartitive)
+    , SuperEssive          (superEssive,          isSuperEssive)
+    , Sublative            (sublative,            isSublative)
+    , Translative          (translative,          isTranslative)
+    , Vocative             (vocative,             isVocative)
+      -- *** Locative cases
+    , LocativeInessive (locativeInessive, isLocativeInessive)
+    , LocativeElative  (locativeElative,  isLocativeElative)
+    , LocativeIllative (locativeIllative, isLocativeIllative)
+    , LocativeAdessive (locativeAdessive, isLocativeAdessive)
+    , LocativeAblative (locativeAblative, isLocativeAblative)
+    , LocativeAllative (locativeAllative, isLocativeAllative)
+      -- ** Gender
+    , NoGender  (noGender,  hasNoGender)
+    , Neuter    (neuter,    isNeuter)
+    , Masculine (masculine, isMasculine)
+    , Feminine  (feminine,  isFeminine)
+    , Common    (common,    isCommon)
+      -- ** Number
+    , NoNumber (noNumber, hasNoNumber)
+    , Singular (singular, isSingular)
+    , Dual     (dual,     isDual)
+    , Trial    (trial,    isTrial)
+    , Paucal   (paucal,   isPaucal)
+    , Plural   (plural,   isPlural)
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Data.Bool ( Bool )
+
+
+--------------------------------------------------------------------------------
+-- Inflection
+--------------------------------------------------------------------------------
+
+-- | Base class for various kinds of inflections.
+class Inflection α
+
+
+--------------------------------------------------------------------------------
+-- Case
+--------------------------------------------------------------------------------
+
+class Inflection α ⇒ NoCase α where
+    noCase ∷ α → α
+    hasNoCase ∷ α → Bool
+
+-- | The ablative case (abbreviated abl) indicates movement from
+-- something, or cause.
+class Inflection α ⇒ Ablative α where
+    ablative ∷ α → α
+    isAblative ∷ α → Bool
+
+-- | In linguistics, abessive (abbreviated abe or abess), caritive and privative
+-- (abbreviated priv) are names for a grammatical case expressing the lack or
+-- absence of the marked noun.
+class Inflection α ⇒ Abessive α where
+    abessive ∷ α → α
+    isAbessive ∷ α → Bool
+
+-- | The accusative case (abbreviated acc) indicates the direct object
+-- of a verb.
+class Inflection α ⇒ Accusative α where
+    accusative ∷ α → α
+    isAccusative ∷ α → Bool
+
+-- | The comitative case (abbreviated com), also known as the associative case
+-- (abbreviated ass), is a grammatical case that denotes companionship, and is
+-- used where English would typically use preposition "with" in the sense of "in
+-- company with" or "together with" (other uses of "with," e.g. with the meaning
+-- of "using," "by means of" (I cut bread with a knife) would correspond to the
+-- instrumental case or related cases).
+class Inflection α ⇒ Comitative α where
+    comitative ∷ α → α
+    isComitative ∷ α → Bool
+
+-- | The dative case (abbreviated dat, or sometimes d when it is a
+-- core argument) indicates the indirect object of a verb.
+class Inflection α ⇒ Dative α where
+    dative ∷ α → α
+    isDative ∷ α → Bool
+
+-- | The delative case (abbreviated del; from Latin deferre "to bear or bring
+-- away or down") in the Hungarian language can originally express the movement
+-- from the surface of something (e.g. "off the table"), but it is used in
+-- several other meanings (e.g. "about people"), some of them related to the
+-- original (e.g. "from the post office").
+class Inflection α ⇒ Delative α where
+    delative ∷ α → α
+    isDelative ∷ α → Bool
+
+-- | The distributive case (abbreviated distr) is used on nouns for the meanings
+-- of per or each.
+class Inflection α ⇒ Distributive α where
+    distributive ∷ α → α
+    isDistributive ∷ α → Bool
+
+-- | The distributive-temporal case specifies when something is done.
+class Inflection α ⇒ DistributiveTemporal α where
+    distributiveTemporal ∷ α → α
+    isDistributiveTemporal ∷ α → Bool
+
+-- | The essive or similaris case (abbreviated ess) carries the meaning of a
+-- temporary location or state of being, often equivalent to the English "as a
+-- (child)".
+class Inflection α ⇒ Essive α where
+    essive ∷ α → α
+    isEssive ∷ α → Bool
+
+-- | The genitive case (abbreviated gen; also called the possessive
+-- case or second case), which roughly corresponds to English's
+-- possessive case and preposition of, indicates the possessor of
+-- another noun.
+class Inflection α ⇒ Genitive α where
+    genitive ∷ α → α
+    isGenitive ∷ α → Bool
+
+-- | The instrumental case (abbreviated ins or instr; also called the
+-- eighth case) indicates an object used in performing an action.
+class Inflection α ⇒ Instrumental α where
+    instrumental ∷ α → α
+    isInstrumental ∷ α → Bool
+
+-- | In the Finnish language and Estonian language, the instructive case has the
+-- basic meaning of "by means of". It is a comparatively rarely used case,
+-- though it is found in some commonly used expressions, such as omin silmin →
+-- "with one's own eyes".
+class Inflection α ⇒ Instructive α where
+    instructive ∷ α → α
+    isInstructive ∷ α → Bool
+
+-- | Lative (abbreviated lat) is a case which indicates motion to a location. It
+-- corresponds to the English prepositions "to" and "into". The lative case
+-- belongs to the group of the general local cases together with the locative
+-- and separative case. The term derives from the Latin lat-, the participle
+-- stem of ferre, "to bring".
+class Inflection α ⇒ Lative α where
+    lative ∷ α → α
+    isLative ∷ α → Bool
+
+-- | The locative case (abbreviated loc) indicates a location.
+class Inflection α ⇒ Locative α where
+    locative ∷ α → α
+    isLocative ∷ α → Bool
+
+-- | The multiplicative case is a grammatical case used for marking a number of
+-- something ("three times").
+class Inflection α ⇒ Multiplicative α where
+    multiplicative ∷ α → α
+    isMultiplicative ∷ α → Bool
+
+-- | The nominative case (abbreviated nom) indicates the subject of a
+-- finite verb.
+class Inflection α ⇒ Nominative α where
+    nominative ∷ α → α
+    isNominative ∷ α → Bool
+
+-- | The partitive case (abbreviated ptv or more ambiguously part)
+-- denotes "partialness", "without result", or "without specific
+-- identity". It is also used in contexts where a subgroup is selected
+-- from a larger group, or with numbers.
+class Inflection α ⇒ Partitive α where
+    partitive ∷ α → α
+    isPartitive ∷ α → Bool
+
+-- | The Superessive case (abbreviated supe) is a grammatical declension
+-- indicating location on top of, or on the surface of something. Its name comes
+-- from Latin supersum, superesse: to be over and above.
+class Inflection α ⇒ SuperEssive α where
+    superEssive ∷ α → α
+    isSuperEssive ∷ α → Bool
+
+-- | The term sublative case (abbreviated subl) is used to refer to grammatical
+-- cases expressing different situations: In Hungarian, it expresses the
+-- destination of the movement, originally to the surface of something (e.g. sit
+-- down on the ground, climb the tree), but in other figurative meanings as well
+-- (e.g. to university, for two nights), while in Tsez and other Northeast
+-- Caucasian languages it denotes a movement towards the bottomsides or the area
+-- under an object. The sublative case is used in the Finnish, Tsez and
+-- Hungarian languages.
+class Inflection α ⇒ Sublative α where
+    sublative ∷ α → α
+    isSublative ∷ α → Bool
+
+-- | The translative case (abbreviated transl) is a grammatical case that
+-- indicates a change in state of a noun, with the general sense of "becoming X"
+-- or "change to X".
+class Inflection α ⇒ Translative α where
+    translative ∷ α → α
+    isTranslative ∷ α → Bool
+
+-- | The vocative case indicates an addressee.
+class Inflection α ⇒ Vocative α where
+    vocative ∷ α → α
+    isVocative ∷ α → Bool
+
+
+--------------------------------------------------------------------------------
+-- Locative cases
+--------------------------------------------------------------------------------
+
+-- | Inessive case (abbreviated ine; from Latin inesse "to be in or at") is a
+-- locative grammatical case. This case carries the basic meaning of "in".
+class Locative α ⇒ LocativeInessive α where
+    locativeInessive ∷ α → α
+    isLocativeInessive ∷ α → Bool
+
+-- | Elative (abbreviated ela; from Latin efferre "to bring or carry out") is a
+-- locative case with the basic meaning "out of".
+class Locative α ⇒ LocativeElative α where
+    locativeElative ∷ α → α
+    isLocativeElative ∷ α → Bool
+
+-- | Illative (abbreviated ill; from Latin illatus "brought in") is, in the
+-- Finnish language, Estonian language and the Hungarian language, the third of
+-- the locative cases with the basic meaning of "into (the inside of)".
+class Locative α ⇒ LocativeIllative α where
+    locativeIllative ∷ α → α
+    isLocativeIllative ∷ α → Bool
+
+-- | In Uralic languages, such as Finnish, Estonian and Hungarian, the adessive
+-- case (abbreviated ade; from Latin adesse "to be present") is the fourth of
+-- the locative cases with the basic meaning of "on".
+class Locative α ⇒ LocativeAdessive α where
+    locativeAdessive ∷ α → α
+    isLocativeAdessive ∷ α → Bool
+
+-- | In linguistics, ablative case (abbreviated abl) is a name given to cases in
+-- various languages whose common characteristic is that they mark motion away
+-- from something, though the details in each language may differ. The name
+-- "ablative" derives from the Latin ablatus, the (irregular) perfect passive
+-- participle of auferre "to carry away".
+class Locative α ⇒ LocativeAblative α where
+    locativeAblative ∷ α → α
+    isLocativeAblative ∷ α → Bool
+
+-- | Allative case (abbreviated all; from Latin allāt-, afferre "to bring to")
+-- is a type of the locative cases used in several languages. The term allative
+-- is generally used for the lative case in the majority of languages which do
+-- not make finer distinctions.
+class Locative α ⇒ LocativeAllative α where
+    locativeAllative ∷ α → α
+    isLocativeAllative ∷ α → Bool
+
+
+--------------------------------------------------------------------------------
+-- Gender
+--------------------------------------------------------------------------------
+
+class Inflection α ⇒ NoGender α where
+    noGender ∷ α → α
+    hasNoGender ∷ α → Bool
+
+class Inflection α ⇒ Neuter α where
+    neuter ∷ α → α
+    isNeuter ∷ α → Bool
+
+class Inflection α ⇒ Masculine α where
+    masculine ∷ α → α
+    isMasculine ∷ α → Bool
+
+class Inflection α ⇒ Feminine α where
+    feminine ∷ α → α
+    isFeminine ∷ α → Bool
+
+class Inflection α ⇒ Common α where
+    common ∷ α → α
+    isCommon ∷ α → Bool
+
+
+--------------------------------------------------------------------------------
+-- Number
+--------------------------------------------------------------------------------
+
+class Inflection α ⇒ NoNumber α where
+    noNumber ∷ α → α
+    hasNoNumber ∷ α → Bool
+
+class Inflection α ⇒ Singular α where
+    singular ∷ α → α
+    isSingular ∷ α → Bool
+
+class Inflection α ⇒ Dual α where
+    dual ∷ α → α
+    isDual ∷ α → Bool
+
+class Inflection α ⇒ Trial α where
+    trial ∷ α → α
+    isTrial ∷ α → Bool
+
+class Inflection α ⇒ Paucal α where
+    paucal ∷ α → α
+    isPaucal ∷ α → Bool
+
+class Inflection α ⇒ Plural α where
+    plural ∷ α → α
+    isPlural ∷ α → Bool
+
diff --git a/src/Text/Numeral/Grammar/Reified.hs b/src/Text/Numeral/Grammar/Reified.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Grammar/Reified.hs
@@ -0,0 +1,277 @@
+{-# LANGUAGE NamedFieldPuns
+           , NoImplicitPrelude
+           , UnicodeSyntax
+           , PackageImports
+  #-}
+
+module Text.Numeral.Grammar.Reified
+    ( -- * Inflection
+      Inflection(..)
+    , defaultInflection
+      -- * Grammatical categories
+    , Case(..)
+    , Gender(..)
+    , Number(..)
+    ) where
+
+
+-------------------------------------------------------------------------------
+-- Imports
+-------------------------------------------------------------------------------
+
+import "base" Data.Bool     ( Bool(False, True) )
+import "base" Data.Eq       ( Eq )
+import "base" Data.Function ( ($) )
+import "base" Data.Maybe    ( Maybe(Nothing, Just) )
+import "base" Text.Show     ( Show )
+import "base-unicode-symbols" Data.Eq.Unicode ( (≡) )
+import qualified "this" Text.Numeral.Grammar as G
+
+
+-------------------------------------------------------------------------------
+-- Inflection
+-------------------------------------------------------------------------------
+
+data Inflection = Inflection { iCase   ∷ Maybe Case
+                             , iGender ∷ Maybe Gender
+                             , iNumber ∷ Maybe Number
+                             } deriving (Show, Eq)
+
+instance G.Inflection Inflection
+
+defaultInflection ∷ Inflection
+defaultInflection = Inflection Nothing Nothing Nothing
+
+
+-------------------------------------------------------------------------------
+-- Grammatical categories
+-------------------------------------------------------------------------------
+
+data Case = Abessive
+          | Ablative
+          | Accusative
+          | Comitative
+          | Dative
+          | Delative
+          | Distributive
+          | DistributiveTemporal
+          | Essive
+          | Genitive
+          | Instrumental
+          | Instructive
+          | Lative
+          | Locative (Maybe Locative)
+          | Multiplicative
+          | Nominative
+          | Partitive
+          | Sublative
+          | SuperEssive
+          | Translative
+          | Vocative
+            deriving (Eq, Show)
+
+data Locative = LocativeIllative
+              | LocativeInessive
+              | LocativeElative
+              | LocativeAllative
+              | LocativeAdessive
+              | LocativeAblative
+                deriving (Eq, Show)
+
+data Gender = Neuter
+            | Masculine
+            | Feminine
+            | Common
+              deriving (Eq, Show)
+
+data Number = Singular
+            | Dual
+            | Trial
+            | Paucal
+            | Plural
+              deriving (Eq, Show)
+
+
+-------------------------------------------------------------------------------
+-- Case instances
+-------------------------------------------------------------------------------
+
+instance G.NoCase Inflection where
+    noCase inf = inf { iCase = Nothing }
+    hasNoCase (Inflection {iCase}) = iCase ≡ Nothing
+
+instance G.Ablative Inflection where
+    ablative inf = inf { iCase = Just Ablative }
+    isAblative (Inflection {iCase}) = iCase ≡ Just Ablative
+
+instance G.Abessive Inflection where
+    abessive inf = inf { iCase = Just Abessive }
+    isAbessive (Inflection {iCase}) = iCase ≡ Just Abessive
+
+instance G.Accusative Inflection where
+    accusative inf = inf { iCase = Just Accusative }
+    isAccusative (Inflection {iCase}) = iCase ≡ Just Accusative
+
+instance G.Comitative Inflection where
+    comitative inf = inf { iCase = Just Comitative }
+    isComitative (Inflection {iCase}) = iCase ≡ Just Comitative
+
+instance G.Dative Inflection where
+    dative inf = inf { iCase = Just Dative }
+    isDative (Inflection {iCase}) = iCase ≡ Just Dative
+
+instance G.Delative Inflection where
+    delative inf = inf { iCase = Just Delative }
+    isDelative (Inflection {iCase}) = iCase ≡ Just Delative
+
+instance G.Distributive Inflection where
+    distributive inf = inf { iCase = Just Distributive }
+    isDistributive (Inflection {iCase}) = iCase ≡ Just Distributive
+
+instance G.DistributiveTemporal Inflection where
+    distributiveTemporal inf = inf { iCase = Just DistributiveTemporal }
+    isDistributiveTemporal (Inflection {iCase}) = iCase ≡ Just DistributiveTemporal
+
+instance G.Essive Inflection where
+    essive inf = inf { iCase = Just Essive }
+    isEssive (Inflection {iCase}) = iCase ≡ Just Essive
+
+instance G.Genitive Inflection where
+    genitive inf = inf { iCase = Just Genitive }
+    isGenitive (Inflection {iCase}) = iCase ≡ Just Genitive
+
+instance G.Instrumental Inflection where
+    instrumental inf = inf { iCase = Just Instrumental }
+    isInstrumental (Inflection {iCase}) = iCase ≡ Just Instrumental
+
+instance G.Instructive Inflection where
+    instructive inf = inf { iCase = Just Instructive }
+    isInstructive (Inflection {iCase}) = iCase ≡ Just Instructive
+
+instance G.Lative Inflection where
+    lative inf = inf { iCase = Just Lative }
+    isLative (Inflection {iCase}) = iCase ≡ Just Lative
+
+instance G.Locative Inflection where
+    locative inf = inf { iCase = Just (Locative Nothing) }
+    isLocative (Inflection {iCase}) =
+        case iCase of
+          Just (Locative _) → True
+          _                 → False
+
+instance G.Multiplicative Inflection where
+    multiplicative inf = inf { iCase = Just Multiplicative }
+    isMultiplicative (Inflection {iCase}) = iCase ≡ Just Multiplicative
+
+instance G.Nominative Inflection where
+    nominative inf = inf { iCase = Just Nominative }
+    isNominative (Inflection {iCase}) = iCase ≡ Just Nominative
+
+instance G.Partitive Inflection where
+    partitive inf = inf { iCase = Just Partitive }
+    isPartitive (Inflection {iCase}) = iCase ≡ Just Partitive
+
+instance G.SuperEssive Inflection where
+    superEssive inf = inf { iCase = Just SuperEssive }
+    isSuperEssive (Inflection {iCase}) = iCase ≡ Just SuperEssive
+
+instance G.Sublative Inflection where
+    sublative inf = inf { iCase = Just Sublative }
+    isSublative (Inflection {iCase}) = iCase ≡ Just Sublative
+
+instance G.Translative Inflection where
+    translative inf = inf { iCase = Just Translative }
+    isTranslative (Inflection {iCase}) = iCase ≡ Just Translative
+
+instance G.Vocative Inflection where
+    vocative inf = inf { iCase = Just Vocative }
+    isVocative (Inflection {iCase}) = iCase ≡ Just Vocative
+
+
+-------------------------------------------------------------------------------
+-- Locative case instances
+-------------------------------------------------------------------------------
+
+instance G.LocativeInessive Inflection where
+    locativeInessive inf = inf {iCase = Just $ Locative $ Just LocativeInessive}
+    isLocativeInessive (Inflection {iCase}) =
+        iCase ≡ (Just $ Locative $ Just LocativeInessive)
+
+instance G.LocativeElative Inflection where
+    locativeElative inf = inf {iCase = Just $ Locative $ Just LocativeElative}
+    isLocativeElative (Inflection {iCase}) =
+        iCase ≡ (Just $ Locative $ Just LocativeElative)
+
+instance G.LocativeIllative Inflection where
+    locativeIllative inf = inf {iCase = Just $ Locative $ Just LocativeIllative}
+    isLocativeIllative (Inflection {iCase}) =
+        iCase ≡ (Just $ Locative $ Just LocativeIllative)
+
+instance G.LocativeAdessive Inflection where
+    locativeAdessive inf = inf {iCase = Just $ Locative $ Just LocativeAdessive}
+    isLocativeAdessive (Inflection {iCase}) =
+        iCase ≡ (Just $ Locative $ Just LocativeAdessive)
+
+instance G.LocativeAblative Inflection where
+    locativeAblative inf = inf {iCase = Just $ Locative $ Just LocativeAblative}
+    isLocativeAblative (Inflection {iCase}) =
+        iCase ≡ (Just $ Locative $ Just LocativeAblative)
+
+instance G.LocativeAllative Inflection where
+    locativeAllative inf = inf {iCase = Just $ Locative $ Just LocativeAllative}
+    isLocativeAllative (Inflection {iCase}) =
+        iCase ≡ (Just $ Locative $ Just LocativeAllative)
+
+
+-------------------------------------------------------------------------------
+-- Gender instances
+-------------------------------------------------------------------------------
+
+instance G.NoGender Inflection where
+    noGender inf = inf { iGender = Nothing }
+    hasNoGender (Inflection {iGender}) = iGender ≡ Nothing
+
+instance G.Neuter Inflection where
+    neuter inf = inf { iGender = Just Neuter }
+    isNeuter (Inflection {iGender}) = iGender ≡ Just Neuter
+
+instance G.Masculine Inflection where
+    masculine inf = inf { iGender = Just Masculine }
+    isMasculine (Inflection {iGender}) = iGender ≡ Just Masculine
+
+instance G.Feminine Inflection where
+    feminine inf = inf { iGender = Just Feminine }
+    isFeminine (Inflection {iGender}) = iGender ≡ Just Feminine
+
+instance G.Common Inflection where
+    common inf = inf { iGender = Just Common }
+    isCommon (Inflection {iGender}) = iGender ≡ Just Common
+
+
+-------------------------------------------------------------------------------
+-- Number instances
+-------------------------------------------------------------------------------
+
+instance G.NoNumber Inflection where
+    noNumber inf = inf { iNumber = Nothing }
+    hasNoNumber (Inflection {iNumber}) = iNumber ≡ Nothing
+
+instance G.Singular Inflection where
+    singular inf = inf { iNumber = Just Singular }
+    isSingular (Inflection {iNumber}) = iNumber ≡ Just Singular
+
+instance G.Dual Inflection where
+    dual inf = inf { iNumber = Just Dual }
+    isDual (Inflection {iNumber}) = iNumber ≡ Just Dual
+
+instance G.Trial Inflection where
+    trial inf = inf { iNumber = Just Trial }
+    isTrial (Inflection {iNumber}) = iNumber ≡ Just Trial
+
+instance G.Paucal Inflection where
+    paucal inf = inf { iNumber = Just Paucal }
+    isPaucal (Inflection {iNumber}) = iNumber ≡ Just Paucal
+
+instance G.Plural Inflection where
+    plural inf = inf { iNumber = Just Plural }
+    isPlural (Inflection {iNumber}) = iNumber ≡ Just Plural
diff --git a/src/Text/Numeral/Language/AF.hs b/src/Text/Numeral/Language/AF.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/AF.hs
@@ -0,0 +1,207 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
+
+{-|
+[@ISO639-1@]        af
+
+[@ISO639-2@]        afr
+
+[@ISO639-3@]        afr
+
+[@Native name@]     Afrikaans
+
+[@English name@]    Afrikaans
+-}
+
+module Text.Numeral.Language.AF
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+    , ordinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Data.Bool     ( otherwise )
+import "base" Data.Function ( ($), const, fix )
+import "base" Data.Maybe    ( Maybe(Just) )
+import "base" Data.Ord      ( (<) )
+import "base" Prelude       ( Integral, (-), negate )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum as BN
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- AF
+--------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "af"
+    , entIso639_2    = ["afr"]
+    , entIso639_3    = Just "afr"
+    , entNativeNames = ["Afrikaans"]
+    , entEnglishName = Just "Afrikaans"
+    , entCardinal    = Just Conversion
+                            { toNumeral   = cardinal
+                            , toStructure = struct
+                            }
+    , entOrdinal     = Just Conversion
+                            { toNumeral   = ordinal
+                            , toStructure = struct
+                            }
+    }
+
+cardinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+ordinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+ordinal inf = ordinalRepr inf ∘ struct
+
+struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
+         )
+       ⇒ α → β
+struct = pos
+       $ fix
+       $ findRule (   0, lit                )
+                [ (  13, add     10      L  )
+                , (  20, mul     10      L L)
+                , ( 100, step1  100   10 R L)
+                , (1000, step1 1000 1000 R L)
+                ]
+                  (dec 6 - 1)
+         `combine` pelletierScale1 R L BN.rule
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 60000 - 1 in (negate x, x)
+
+genericRepr ∷ Repr i
+genericRepr = defaultRepr
+               { reprAdd   = Just (⊞)
+               , reprMul   = Just (⊡)
+               , reprNeg   = Just $ \_ _   → "min "
+               }
+    where
+      (_     ⊞ Lit 10) _         = ""
+      (Lit n ⊞ _) _ | n < 10     = "-en-"
+                    | otherwise  = ""
+      (_     ⊞ _) _              = " "
+
+      (_ ⊡ Lit _) _ = ""
+      (_ ⊡ _    ) _ = " "
+
+cardinalRepr ∷ i → Exp i → Maybe Text
+cardinalRepr = render genericRepr
+               { reprValue = \_ n → M.lookup n syms
+               , reprScale = BN.pelletierRepr (\_ _ → "iljoen")
+                                              (\_ _ → "iljard")
+                                              []
+               }
+    where
+      syms =
+          M.fromList
+          [ (0, const "nul")
+          , (1, const "een")
+          , (2, forms "twee" "twin")
+          , (3, forms "drie" "der")
+          , (4, forms "vier" "veer")
+          , (5, const "vyf")
+          , (6, const "ses")
+          , (7, forms "sewe" "sewen")
+          , (8, \c → case c of
+                       CtxMul _ (Lit 10) _ → "tag"
+                       _                   → "ag"
+            )
+          , (9, \c → case c of
+                       CtxAdd _ (Lit 10) _ → "negen"
+                       CtxMul _ (Lit 10) _ → "neën"
+                       _                   → "nege"
+            )
+          , (10, \c → case c of
+                        CtxMul R _ _ → "tig"
+                        _            → "tien"
+            )
+          , (11, const "elf")
+          , (12, const "twaalf")
+          , (100, const "honderd")
+          , (1000, const "duisend")
+          ]
+
+      forms ∷ s → s → Ctx (Exp i) → s
+      forms n t ctx = case ctx of
+                        CtxMul _ (Lit 10) _ → t
+                        CtxAdd _ (Lit 10) _ → t
+                        CtxAdd _ (Lit _)  _ → n
+                        _                   → n
+
+ordinalRepr ∷ i → Exp i → Maybe Text
+ordinalRepr = render genericRepr
+              { reprValue = \_ n → M.lookup n syms
+              , reprScale = BN.pelletierRepr (\_ _ → "iljoen")
+                                             (\_ _ → "iljard")
+                                             []
+              }
+    where
+      syms =
+          M.fromList
+          [ (0, const "nul")
+          , (1, \c → case c of
+                       CtxEmpty          → "eerste"
+                       _ | isOutside R c → "eende"
+                         | otherwise     → "een"
+            )
+          , (2, forms "tweede" "twee" "twin")
+          , (3, forms "derde"  "drie" "der")
+          , (4, forms "vierde" "vier" "veer")
+          , (5, \c → if isOutside R c then "vyfde" else "vyf")
+          , (6, \c → if isOutside R c then "sesde" else "ses")
+          , (7, forms "sewende" "sewe" "sewen")
+          , (8, \c → case c of
+                       _ | isOutside R c   → "agtste"
+                       CtxMul _ (Lit 10) _ → "tag"
+                       _                   → "ag"
+            )
+          , (9, \c → case c of
+                       _ | isOutside R c   → "negende"
+                       CtxAdd _ (Lit 10) _ → "negen"
+                       CtxMul _ (Lit 10) _ → "neën"
+                       _                   → "nege"
+            )
+          , (10, \c → case c of
+                        CtxMul R _ _ | isOutside R c → "tigste"
+                                     | otherwise     → "tig"
+                        _            | isOutside R c → "tiende"
+                                     | otherwise     → "tien"
+            )
+          , (11, \c → if isOutside R c then "elfde" else "elf")
+          , (12, \c → if isOutside R c then "twaalfde" else "twaalf")
+          , (100, \c → if isOutside R c then "honderste" else "honderd")
+          , (1000, \c → if isOutside R c then "duisendste" else "duisend")
+          ]
+
+      forms ∷ s → s → s → Ctx (Exp i) → s
+      forms o c t ctx = case ctx of
+                          _ | isOutside R ctx → o
+                          CtxMul _ (Lit 10) _ → t
+                          CtxAdd _ (Lit 10) _ → t
+                          CtxAdd _ (Lit _)  _ → c
+                          _                   → c
diff --git a/src/Text/Numeral/Language/AMP.hs b/src/Text/Numeral/Language/AMP.hs
--- a/src/Text/Numeral/Language/AMP.hs
+++ b/src/Text/Numeral/Language/AMP.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        -
@@ -17,8 +16,14 @@
 -}
 
 module Text.Numeral.Language.AMP
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -28,28 +33,34 @@
 
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
 import "base" Prelude       ( Integral )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import "numerals-base" Text.Numeral
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 -------------------------------------------------------------------------------
 -- AMP
 -------------------------------------------------------------------------------
 
-{-
-Sources:
-  http://www.sf.airnet.ne.jp/~ts/language/number/alamblak.html
--}
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_3    = Just "amp"
+    , entEnglishName = Just "Alamblak"
+    , entCardinal    = Just Conversion
+                            { toNumeral   = cardinal
+                            , toStructure = struct
+                            }
+    }
 
-cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ α → β
 struct = checkPos
        $ fix
        $ findRule ( 1, lit       )
@@ -63,9 +74,12 @@
                 ]
                   399
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (1, 399)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprAdd   = Just (⊞)
                , reprMul   = Just $ \_ _ _ → " "
                }
diff --git a/src/Text/Numeral/Language/BG.hs b/src/Text/Numeral/Language/BG.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/BG.hs
@@ -0,0 +1,185 @@
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        bg
+
+[@ISO639-2@]        bul
+
+[@ISO639-3@]        bul
+
+[@Native name@]     Български език
+
+[@English name@]    Bulgarian
+-}
+
+module Text.Numeral.Language.BG
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Data.Bool     ( otherwise )
+import "base" Data.Function ( ($), const, fix )
+import "base" Data.Maybe    ( Maybe(Just) )
+import "base" Prelude       ( Integral, (-), negate )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Data.Ord.Unicode      ( (≤) )
+import "base-unicode-symbols" Prelude.Unicode       ( ℤ )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum  as BN
+import qualified "this" Text.Numeral.Exp     as E
+import qualified "this" Text.Numeral.Grammar as G
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- BG
+--------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "bg"
+    , entIso639_2    = ["bul"]
+    , entIso639_3    = Just "bul"
+    , entNativeNames = ["Български език"]
+    , entEnglishName = Just "Bulgarian"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
+
+cardinal ∷ (G.Neuter i, G.Feminine i, G.Masculine i, Integral α, E.Scale α)
+         ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
+         , E.Inflection β, G.Masculine (E.Inf β)
+         )
+       ⇒ α → β
+struct = pos $ fix $ rule `combine` shortScale1_bg
+    where
+       rule = findRule (   0, lit               )
+                     [ (  13, add 10 L          )
+                     , (  20, mul 10 R L        )
+                     , ( 100, step  100   10 R L)
+                     , (1000, step 1000 1000 R L)
+                     ]
+                     (dec 6 - 1)
+
+-- | Like 'shortScale1' but forces the right-hand-side to have
+-- masculine gender.
+shortScale1_bg ∷ ( Integral α, E.Scale α
+                 , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
+                 , E.Inflection β, G.Masculine (E.Inf β)
+                 )
+               ⇒ Rule α β
+shortScale1_bg = mulScale_ bgMul 3 3 R L rule
+    where
+      bgMul f m scale' _ = masculineMul (f m) scale'
+      masculineMul x y = E.inflection G.masculine $ E.mul x y
+      rule = findRule (1, lit) [] 14
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 48 - 1 in (negate x, x)
+
+cardinalRepr ∷ (G.Neuter i, G.Feminine i, G.Masculine i) ⇒ i → Exp i → Maybe Text
+cardinalRepr = render defaultRepr
+               { reprValue = \inf n → M.lookup n (syms inf)
+               , reprScale = shortScaleRepr
+               , reprAdd   = Just (⊞)
+               , reprMul   = Just (⊡)
+               , reprNeg   = Just $ \_ _ → "минус "
+               }
+    where
+      (Lit 100 ⊞  Lit _) _          = " и "
+      (_ ⊞ Add _ (Lit 10)) _        = " и "
+      (_ ⊞ Mul _ (Lit 10)) _        = " и "
+      (_ ⊞ Lit 10) _                = ""
+      ((_ `Mul` Lit _) ⊞ Lit _) _   = " и "
+      (Inflection _ _ ⊞ Lit _) _    = " и "
+      (_     ⊞ _     ) _            = " "
+
+      (_ ⊡ Lit n) _ | n ≤ 100 = ""
+      (_ ⊡ _    ) _           = " "
+
+      syms inf =
+          M.fromList
+          [ (0, const "нула")
+          , (1, const $ if G.isFeminine inf
+                        then "една"
+                        else if G.isMasculine inf
+                             then "един"
+                             else "едно"
+            )
+          , (2, \c → case c of
+                       CtxMul _ (Lit   10) _ → "два"
+                       CtxMul _ (Lit  100) _ → "две"
+                       CtxMul _ (Lit 1000) _ → "две"
+                       _ | G.isMasculine inf → "два"
+                         | otherwise         → "две"
+            )
+          , (3, const "три")
+          , (4, const "четири")
+          , (5, const "пет")
+          , (6, const "шест")
+          , (7, const "седем")
+          , (8, const "осем")
+          , (9, const "девет")
+          , (10, \c → case c of
+                        CtxAdd _ (Lit n) _ | n ≤ 9 → "надесет"
+                        _                          → "десет"
+            )
+          , (11, const "единадесет")
+          , (12, const "дванадесет")
+          , (100, \c → case c of
+                         CtxMul _ (Lit 2) _ → "ста"
+                         CtxMul _ (Lit 3) _ → "ста"
+                         CtxMul R _ _       → "стотин"
+                         _                  → "сто"
+            )
+          , (1000, \c → case c of
+                          CtxMul R _ _ → "хиляди"
+                          _            → "хиляда"
+            )
+          ]
+
+shortScaleRepr ∷ i → ℤ → ℤ → (Exp i) → Ctx (Exp i) → Maybe Text
+shortScaleRepr inf b o e
+    = case e of
+        Lit 2 → BN.scaleRepr (BN.quantityName "илиард" "илиарда") syms inf b o e
+        _ → BN.scaleRepr (BN.quantityName "илион" "илиона") syms inf b o e
+    where
+      syms = [ ( 1, const "м")
+             , ( 2, const "м")
+             , ( 3, const "тр")
+             , ( 4, const "квадр")
+             , ( 5, const "квинт")
+             , ( 6, const "секст")
+             , ( 7, const "септ")
+             , ( 8, const "окт")
+             , ( 9, const "нон")
+             , (10, const "дец")
+             , (11, const "индец")
+             , (12, const "дуодец")
+             , (13, const "тридец")
+             , (14, const "куадродец")
+             ]
diff --git a/src/Text/Numeral/Language/CHN.hs b/src/Text/Numeral/Language/CHN.hs
--- a/src/Text/Numeral/Language/CHN.hs
+++ b/src/Text/Numeral/Language/CHN.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        -
@@ -11,14 +10,20 @@
 
 [@ISO639-3@]        chn
 
-[@Native name@]     -
+[@Native name@]     chinuk wawa
 
 [@English name@]    Chinook Jargon
 -}
 
 module Text.Numeral.Language.CHN
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -28,23 +33,36 @@
 
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
 import "base" Prelude       ( Integral )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import "numerals-base" Text.Numeral
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- CHN
 --------------------------------------------------------------------------------
 
-cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_2    = ["chn"]
+    , entIso639_3    = Just "chn"
+    , entNativeNames = ["chinuk wawa"]
+    , entEnglishName = Just "Chinook Jargon"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ α → β
 struct = checkPos
        $ fix
        $ findRule (  0, lit           )
@@ -53,9 +71,12 @@
                 ]
                    100
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (0, 100)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprAdd   = Just $ \_ _ _ → " pe "
                , reprMul   = Just $ \_ _ _ → " "
                }
diff --git a/src/Text/Numeral/Language/CHR.hs b/src/Text/Numeral/Language/CHR.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/CHR.hs
@@ -0,0 +1,244 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        chr
+
+[@ISO639-3@]        chr
+
+[@Native name@]     ᏣᎳᎩ ᎦᏬᏂᎯᏍᏗ (Tsalagi Gawonihisdi)
+
+[@English name@]    Cherokee
+-}
+
+module Text.Numeral.Language.CHR
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+      -- * Transliteration
+    , transliterate
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Data.Char     ( Char )
+import "base" Data.Function ( ($), const, fix )
+import "base" Data.Maybe    ( Maybe(Just) )
+import "base" Prelude       ( Integral, (-), String )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
+import qualified "text" Data.Text as T ( concatMap, singleton )
+
+
+--------------------------------------------------------------------------------
+-- CHR
+--------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_2    = ["chr"]
+    , entIso639_3    = Just "chr"
+    , entNativeNames = let n = "ᏣᎳᎩ ᎦᏬᏂᎯᏍᏗ" in [n, transliterate n]
+    , entEnglishName = Just "Cherokee"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
+
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ α → β
+struct = checkPos
+       $ fix
+       $ findRule (   0, lit                )
+                [ (  11, add   10        L  )
+                , (  20, step  10   10   R L)
+                , ( 100, step1 100  10   R L)
+                , (1000, step1 1000 1000 R L)
+                ]
+                  (dec 6 - 1)
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (0, dec 6 - 1)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
+cardinalRepr = render defaultRepr
+               { reprValue = \_ n → M.lookup n syms
+               , reprAdd   = Just (⊞)
+               , reprMul   = Just (⊡)
+               }
+    where
+      (Mul _ _ ⊞ _) _ = " "
+      (Lit 100 ⊞ _) _ = " "
+      (_       ⊞ _) _ = ""
+
+      (Lit _ ⊡ Lit 100) CtxEmpty = ""
+      (Lit _ ⊡ Lit 100) _ = " "
+      (_     ⊡ Lit 1000) _ = " "
+      (_     ⊡ _       ) _ = ""
+
+      syms =
+          M.fromList
+          [ (0, const "Ꮭ ᎪᏍᏗ")
+          , (1, \c → case c of
+                       CtxAdd L (Lit 10) _ → "Ꮜ"
+                       CtxAdd R _        _ → "ᏌᏬ"
+                       _                   → "ᏐᏬ"
+            )
+          , (2, const "ᏔᎵ")
+          , (3, \c → case c of
+                       CtxAdd L (Lit 10)  _ → "ᏦᎦ"
+                       CtxMul _ (Lit 100) CtxEmpty → "Ꮶ"
+                       CtxMul _ (Lit 100) _ → "ᏦᎢ"
+                       _                    → "ᏦᎢ"
+            )
+          , (4, \c → case c of
+                       CtxAdd L (Lit 10) _ → "ᏂᎦ"
+                       _                   → "ᏅᎩ"
+            )
+          , (5, \c → case c of
+                       CtxAdd L (Lit 10) _ → "ᎯᏍᎦ"
+                       _                   → "ᎯᏍᎩ"
+            )
+          , (6, \c → case c of
+                       CtxAdd L (Lit 10) _ → "ᏓᎳ"
+                       _                   → "ᏑᏓᎵ"
+            )
+          , (7, \c → case c of
+                       CtxAdd L (Lit 10)  _ → "ᎦᎵᏆ"
+                       CtxMul _ (Lit 100) CtxEmpty → "ᎦᎵᏆ"
+                       CtxMul _ (Lit 100) _ → "ᎦᎵᏉᎩ"
+                       CtxMul _ _         _ → "ᎦᎵᏆ"
+                       _                    → "ᎦᎵᏉᎩ"
+            )
+          , (8, \c → case c of
+                       CtxAdd L (Lit 10)  _ → "ᏁᎳ"
+                       CtxMul _ (Lit 100) CtxEmpty → "ᏧᏁᎵ"
+                       _                    → "ᏧᏁᎳ"
+            )
+          , (9, \c → case c of
+                       CtxMul _ (Lit 100) _ → "ᏐᏁᎵ"
+                       _                    → "ᏐᏁᎳ"
+            )
+          , (10, \c → case c of
+                        CtxAdd R (Lit _) _           → "Ꮪ"
+                        CtxMul R (Lit _) (CtxAdd {}) → "ᏍᎪ"
+                        _                            → "ᏍᎪᎯ"
+            )
+          , (100, const "ᏍᎪᎯᏥᏆ")
+          , (1000, const "ᎢᏯᎦᏴᎵ")
+          ]
+
+-- | Transliterates a string written in the Cherokee syllabary to the
+-- latin alphabet.
+transliterate ∷ Text → Text
+transliterate xs = T.concatMap f xs
+    where
+      f ∷ Char → Text
+      f 'Ꭰ' = "a"
+      f 'Ꭱ' = "e"
+      f 'Ꭲ' = "i"
+      f 'Ꭳ' = "o"
+      f 'Ꭴ' = "u"
+      f 'Ꭵ' = "v"
+      f 'Ꭶ' = "ga"
+      f 'Ꭷ' = "ka"
+      f 'Ꭸ' = "ge"
+      f 'Ꭹ' = "gi"
+      f 'Ꭺ' = "go"
+      f 'Ꭻ' = "gu"
+      f 'Ꭼ' = "gv"
+      f 'Ꭽ' = "ha"
+      f 'Ꭾ' = "he"
+      f 'Ꭿ' = "hi"
+      f 'Ꮀ' = "ho"
+      f 'Ꮁ' = "hu"
+      f 'Ꮂ' = "hv"
+      f 'Ꮃ' = "la"
+      f 'Ꮄ' = "le"
+      f 'Ꮅ' = "li"
+      f 'Ꮆ' = "lo"
+      f 'Ꮇ' = "lu"
+      f 'Ꮈ' = "lv"
+      f 'Ꮉ' = "ma"
+      f 'Ꮊ' = "me"
+      f 'Ꮋ' = "mi"
+      f 'Ꮌ' = "mo"
+      f 'Ꮍ' = "mu"
+      f 'Ꮎ' = "na"
+      f 'Ꮏ' = "hna"
+      f 'Ꮐ' = "nah"
+      f 'Ꮑ' = "ne"
+      f 'Ꮒ' = "ni"
+      f 'Ꮓ' = "no"
+      f 'Ꮔ' = "nu"
+      f 'Ꮕ' = "nv"
+      f 'Ꮖ' = "qua"
+      f 'Ꮗ' = "que"
+      f 'Ꮘ' = "qui"
+      f 'Ꮙ' = "quo"
+      f 'Ꮚ' = "quu"
+      f 'Ꮛ' = "quv"
+      f 'Ꮝ' = "s"
+      f 'Ꮜ' = "sa"
+      f 'Ꮞ' = "se"
+      f 'Ꮟ' = "si"
+      f 'Ꮠ' = "so"
+      f 'Ꮡ' = "su"
+      f 'Ꮢ' = "sv"
+      f 'Ꮣ' = "da"
+      f 'Ꮤ' = "ta"
+      f 'Ꮥ' = "de"
+      f 'Ꮦ' = "te"
+      f 'Ꮧ' = "di"
+      f 'Ꮨ' = "ti"
+      f 'Ꮩ' = "do"
+      f 'Ꮪ' = "du"
+      f 'Ꮫ' = "dv"
+      f 'Ꮬ' = "dla"
+      f 'Ꮭ' = "tla"
+      f 'Ꮮ' = "tle"
+      f 'Ꮯ' = "tli"
+      f 'Ꮰ' = "tlo"
+      f 'Ꮱ' = "tlu"
+      f 'Ꮲ' = "tlv"
+      f 'Ꮳ' = "tsa"
+      f 'Ꮴ' = "tse"
+      f 'Ꮵ' = "tsi"
+      f 'Ꮶ' = "tso"
+      f 'Ꮷ' = "tsu"
+      f 'Ꮸ' = "tsv"
+      f 'Ꮹ' = "wa"
+      f 'Ꮺ' = "we"
+      f 'Ꮻ' = "wi"
+      f 'Ꮼ' = "wo"
+      f 'Ꮽ' = "wu"
+      f 'Ꮾ' = "wv"
+      f 'Ꮿ' = "ya"
+      f 'Ᏸ' = "ye"
+      f 'Ᏹ' = "yi"
+      f 'Ᏺ' = "yo"
+      f 'Ᏻ' = "yu"
+      f 'Ᏼ' = "yv"
+      f c   = T.singleton c
+
diff --git a/src/Text/Numeral/Language/CLM.hs b/src/Text/Numeral/Language/CLM.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/CLM.hs
@@ -0,0 +1,115 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2B@]       -
+
+[@ISO639-3@]        clm
+
+[@Native name@]     nəxʷsƛ̕ay̕əmúcən
+
+[@English name@]    Klallam
+-}
+
+module Text.Numeral.Language.CLM
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Data.Function ( ($), const, fix )
+import "base" Data.Maybe    ( Maybe(Just) )
+import "base" Prelude       ( Integral )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- CLM
+--------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_3    = Just "clm"
+    , entNativeNames = ["nəxʷsƛ̕ay̕əmúcən"]
+    , entEnglishName = Just "Klallam"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
+
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ α → β
+struct = fix
+       $ findRule (   1, lit            )
+                [ (  11, add 10 R       )
+                , (  20, lit            )
+                , (  21, add 20 R       )
+                , (  30, step 10 10 R L )
+                , ( 100, lit            )
+                , ( 101, step 100 10 R L)
+                , (1000, mul 100 R L    )
+                ]
+                  1000
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (1, 1000)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
+cardinalRepr = render defaultRepr
+               { reprValue = \_ n → M.lookup n syms
+               , reprAdd   = Just $ \_ _ _ → " ʔiʔ "
+               , reprMul   = Just (⊡)
+               }
+    where
+      (_ ⊡ Lit 100) _ = " "
+      (_ ⊡ _      ) _ = ""
+
+      syms =
+          M.fromList
+          [ (1, const "nə́c̕uʔ")
+          , (2, const "čə́saʔ")
+          , (3, forms "ɬíxʷ"   "ɬxʷ"   )
+          , (4, forms "ŋús"    "ŋəs"   )
+          , (5, forms "ɬq̕áčš"  "ɬq̕čš"  )
+          , (6, forms "t̕x̣ə́ŋ"   "t̕x̣əŋ"  )
+          , (7, forms "c̕úʔkʷs" "c̕aʔkʷs")
+          , (8, forms "táʔcs"  "taʔcs" )
+          , (9, forms "tə́kʷxʷ" "təkʷxʷ")
+          , (10, \c → case c of
+                        CtxMul R _ _ → "ɬšáʔ"
+                        _            → "ʔúpən"
+            )
+          , (20, const "nəc̕xʷk̕ʷə́s")
+          , (100, const "snáč̕əwəč")
+          ]
+
+      forms ∷ s
+            → s
+            → Ctx (Exp i)
+            → s
+      forms n t ctx = case ctx of
+                        CtxMul _ (Lit 10) _ → t
+                        _                   → n
diff --git a/src/Text/Numeral/Language/CS.hs b/src/Text/Numeral/Language/CS.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/CS.hs
@@ -0,0 +1,154 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        cs
+
+[@ISO639-2B@]       cze
+
+[@ISO639-2T@]       ces
+
+[@ISO639-3@]        ces
+
+[@Native name@]     Čeština
+
+[@English name@]    Czech
+-}
+
+module Text.Numeral.Language.CS
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    ) where
+
+
+-------------------------------------------------------------------------------
+-- Imports
+-------------------------------------------------------------------------------
+
+import "base" Data.Bool     ( otherwise )
+import "base" Data.Function ( const )
+import "base" Data.Maybe    ( Maybe(Just) )
+import "base" Prelude       ( Integral, (-), negate )
+import "base-unicode-symbols" Data.Eq.Unicode       ( (≡) )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Data.Ord.Unicode      ( (≤) )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum as BN
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "this" Text.Numeral.Language.PL ( struct )
+import "text" Data.Text ( Text )
+
+
+-------------------------------------------------------------------------------
+-- CS
+-------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "cs"
+    , entIso639_2    = ["cze", "ces"]
+    , entIso639_3    = Just "ces"
+    , entNativeNames = ["Čeština"]
+    , entEnglishName = Just "Czech"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
+
+cardinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 60000 - 1 in (negate x, x)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
+cardinalRepr = render defaultRepr
+               { reprValue = \_ n → M.lookup n syms
+               , reprScale = BN.pelletierRepr (quantityRepr "ilión"   "ilióny"  "iliónů")
+                                              (quantityRepr "iliarda" "iliarda" "iliarda")
+                                              []
+               , reprAdd   = Just (⊞)
+               , reprMul   = Just (⊡)
+               }
+    where
+      (Lit n ⊞ Lit 10) _ | n ≤ 9 = ""
+      (_     ⊞ _     ) _         = " "
+
+      (_ ⊡ Lit 10 ) _ = ""
+      (_ ⊡ Lit 100) _ = " "
+      (_ ⊡ _      ) _ = " "
+
+      quantityRepr ∷ Text → Text → Text → BN.PostfixRepr i
+      quantityRepr s p1 p2 _ ctx =
+          case ctx of
+            CtxMul _ (Lit 1) _ → s
+            CtxMul _ (Lit n) _ | n ≤ 4 → p1
+            CtxMul {}          → p2
+            _                  → s
+
+      syms =
+          M.fromList
+          [ (0,  const                         "nula")
+          , (1,  \c → case c of
+                        CtxAdd _ (Lit 10)  _ → "jede"
+                        CtxAdd {}            → "jedna"
+                        _                    → "jeden"
+            )
+          , (2,  \c → case c of
+                        CtxMul _ (Lit 100) _ → "dvě"
+                        _                    → "dva"
+            )
+          , (3, const                          "tři")
+          , (4,  \c → case c of
+                        CtxAdd _ (Lit 10)  _ → "ctr"
+                        _                    → "čtyři"
+            )
+          , (5,  \c → case c of
+                        CtxAdd _ (Lit 10)  _ → "pat"
+                        CtxMul _ (Lit 10)  _ → "pa"
+                        _                    → "pět"
+            )
+          , (6,  \c → case c of
+                        CtxMul _ (Lit 10)  _ → "še"
+                        _                    → "šest"
+            )
+          , (7,  const                         "sedm")
+          , (8,  const                         "osm")
+          , (9,  \c → case c of
+                        CtxAdd _ (Lit 10)  _ → "devate"
+                        CtxMul _ (Lit 10)  _ → "devá"
+                        _                    → "devět"
+            )
+          , (10,  \c → case c of
+                         CtxAdd R (Lit n) _
+                             | n ≤ 9     → "náct"
+                         CtxMul R (Lit n) _
+                             | n ≤ 4     → "cet"
+                             | otherwise → "desát"
+                         _               → "deset"
+            )
+          , (100, \c → case c of
+                         CtxMul _ (Lit n) _
+                             | n ≡ 2 → "stě"
+                             | n ≤ 4 → "sta"
+                             | n ≤ 9 → "set"
+                         _           → "sto"
+            )
+          , (1000, \c → case c of
+                          CtxMul _ (Lit n) _ | n ≤ 4 → "tisíce"
+                          _                          → "tisíc"
+            )
+          ]
diff --git a/src/Text/Numeral/Language/DE.hs b/src/Text/Numeral/Language/DE.hs
--- a/src/Text/Numeral/Language/DE.hs
+++ b/src/Text/Numeral/Language/DE.hs
@@ -1,14 +1,16 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
 
 {-|
 [@ISO639-1@]        de
 
 [@ISO639-2B@]       ger
 
+[@ISO639-2T@]       deu
+
 [@ISO639-3@]        deu
 
 [@Native name@]     Deutsch
@@ -17,8 +19,15 @@
 -}
 
 module Text.Numeral.Language.DE
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+    , ordinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -29,62 +38,94 @@
 import "base" Data.Bool     ( otherwise )
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
-import "base" Prelude       ( Integral, (-), Integer )
+import "base" Prelude       ( Integral, (-), negate )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import "base-unicode-symbols" Data.List.Unicode     ( (∈) )
-import "base-unicode-symbols" Data.Ord.Unicode      ( (≥) )
+import "base-unicode-symbols" Data.Ord.Unicode      ( (≤), (≥) )
+import "base-unicode-symbols" Prelude.Unicode       ( ℤ )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.BigNum      as BN
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum as BN
+import qualified "this" Text.Numeral.Exp    as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 -------------------------------------------------------------------------------
 -- DE
 -------------------------------------------------------------------------------
 
-{-
-Sources:
-  http://de.wikipedia.org/wiki/Zahlennamen
--}
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "de"
+    , entIso639_2    = ["ger", "deu"]
+    , entIso639_3    = Just "deu"
+    , entNativeNames = ["Deutsch"]
+    , entEnglishName = Just "German"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    , entOrdinal     = Just Conversion
+                       { toNumeral   = ordinal
+                       , toStructure = struct
+                       }
+    }
 
-cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
 
-struct ∷ ( Integral α, C.Scale α
-         , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β
+ordinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+ordinal inf = ordinalRepr inf ∘ struct
+
+struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
          )
        ⇒ α → β
-struct = pos $ fix $ rule `combine` pelletierScale R L BN.rule
+struct = pos
+       $ fix
+       $ findRule (   0, lit       )
+               [ (  13, add 10 L  )
+               , (  20, mul 10 L L)
+               , ( 100, step 100    10 R L)
+               , (1000, step 1000 1000 R L)
+               ]
+                 (dec 6 - 1)
+         `combine` pelletierScale R L BN.rule
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 60000 - 1 in (negate x, x)
+
+genericRepr ∷ Repr i
+genericRepr = defaultRepr
+              { reprAdd   = Just (⊞)
+              , reprMul   = Just (⊡)
+              , reprNeg   = Just $ \_ _   → "minus "
+              }
     where
-      rule = findRule (   0, lit       )
-                    [ (  13, add 10 L  )
-                    , (  20, mul 10 L L)
-                    , ( 100, step1 100   10 R L)
-                    , (1000, step 1000 1000 R L)
-                    ]
-                      (dec 6 - 1)
+      (Lit n ⊞ (_ `Mul` Lit 10)) _ | n ≤ 9 = "und"
+      (_ ⊞ _ ) _ = ""
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
-cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
-               , reprScale = pelletierRepr
-               , reprAdd   = Just (⊞)
-               , reprMul   = Just $ \_ _ _ → ""
-               , reprNeg   = Just $ \_ _   → "minus "
+      (_ ⊡ Scale _ _ _) _ = " "
+      (_ ⊡ _)           _ = ""
+
+
+cardinalRepr ∷ i → Exp i → Maybe Text
+cardinalRepr = render genericRepr
+               { reprValue = \_ n → M.lookup n syms
+               , reprScale = BN.pelletierRepr (BN.quantityName "illion"   "illionen")
+                                              (BN.quantityName "illiarde" "illiarden")
+                                              bigNumSyms
                }
     where
-      (_ ⊞ (_ `Mul` Lit 10)) _ = "und"
-      (_ ⊞ _               ) _ = ""
-
       syms =
           M.fromList
           [ (0, const "null")
           , (1, \c → case c of
-                       CtxAdd {}        → "ein"
+                       CtxAdd R _ _     → "eins"
+                       CtxAdd L _ _     → "ein"
                        CtxMul _ (Lit n) _
                            | n ≥ dec 6  → "eine"
                            | n ≥ 100    → "ein"
@@ -111,7 +152,7 @@
           , (9, const "neun")
           , (10, \c → case c of
                         CtxMul _ (Lit 3) _ → "ßig"
-                        CtxMul _ (Lit _) _ → "zig"
+                        CtxMul R (Lit _) _ → "zig"
                         _                  → "zehn"
             )
           , (11, const "elf")
@@ -120,23 +161,81 @@
           , (1000, const "tausend")
           ]
 
-pelletierRepr ∷ (IsString s, Monoid s)
-              ⇒ Integer → Integer → Exp → Ctx Exp → Maybe s
-pelletierRepr =
-    BN.pelletierRepr
-      "illion"   "illion"
-      "illiarde" "illiarde"
-      [ (8, BN.forms "okt" "okto" "okto" "okto" "oktin")
-      , (10, \c → case c of
-                    CtxAdd _ (Lit 100) _              → "dezi"
-                    CtxMul _ _ (CtxAdd _ (Lit 100) _) → "ginta"
-                    CtxMul {}                         → "gint"
-                    _                                 → "dez"
-        )
-      , (100, \c → case c of
-                     CtxMul _ (Lit n) _
-                         | n ∈ [2,3,6] → "zent"
-                         | otherwise   → "gent"
-                     _                 → "zent"
-        )
-      ]
+ordinalRepr ∷ i → Exp i → Maybe Text
+ordinalRepr = render genericRepr
+              { reprValue = \_ n → M.lookup n syms
+              , reprScale = BN.pelletierRepr (BN.ordQuantityName "illion" "illionste"
+                                                                 "illion" "illionste"
+                                             )
+                                             (BN.ordQuantityName "illiarde" "illiardste"
+                                                                 "illiarde" "illiardste"
+                                             )
+                                             bigNumSyms
+              }
+    where
+      syms =
+          M.fromList
+          [ (0, \c → case c of
+                       CtxEmpty → "nullte"
+                       _        → "null"
+            )
+          , (1, \c → case c of
+                       _ | isOutside R c → "erste"
+                       CtxAdd {}         → "ein"
+                       CtxMul _ (Lit n) _
+                           | n ≥ dec 6   → "eine"
+                           | n ≥ 100     → "ein"
+                       _                 → "eins"
+            )
+          , (2, \c → case c of
+                       _ | isOutside R c   → "zweite"
+                       CtxMul _ (Lit 10) _ → "zwan"
+                       _                   → "zwei"
+            )
+          , (3, \c → if isOutside R c then "dritte" else "drei")
+          , (4, \c → if isOutside R c then "vierte" else "vier")
+          , (5, \c → if isOutside R c then "fünfte" else "fünf")
+          , (6, \c → case c of
+                       _ | isOutside R c   → "sechste"
+                       CtxAdd _ (Lit 10) _ → "sech"
+                       CtxMul _ (Lit 10) _ → "sech"
+                       _                   → "sechs"
+            )
+          , (7, \c → case c of
+                       _ | isOutside R c   → "siebte"
+                       CtxAdd _ (Lit 10) _ → "sieb"
+                       CtxMul _ (Lit 10) _ → "sieb"
+                       _                   → "sieben"
+            )
+          , (8, \c → if isOutside R c then "achte"  else "acht")
+          , (9, \c → if isOutside R c then "neunte" else "neun")
+          , (10, \c → case c of
+                        CtxMul _ (Lit 3) _ | isOutside R c → "ßigste"
+                                           | otherwise     → "ßig"
+                        CtxMul R (Lit _) _ | isOutside R c → "zigste"
+                                           | otherwise     → "zig"
+                        _                  | isOutside R c → "zehnte"
+                                           | otherwise     → "zehn"
+            )
+          , (11, \c → if isOutside R c then "elfte"   else "elf")
+          , (12, \c → if isOutside R c then "zwölfte" else "zwölf")
+          , (100, \c → if isOutside R c then "hundertste" else "hundert")
+          , (1000, \c → if isOutside R c then "tausendste" else "tausend")
+          ]
+
+bigNumSyms ∷ [(ℤ, Ctx (Exp i) → Text)]
+bigNumSyms =
+    [ (8, BN.forms "okt" "okto" "okto" "okto" "oktin")
+    , (10, \c → case c of
+                  CtxAdd _ (Lit 100) _              → "dezi"
+                  CtxMul _ _ (CtxAdd _ (Lit 100) _) → "ginta"
+                  CtxMul {}                         → "gint"
+                  _                                 → "dez"
+      )
+    , (100, \c → case c of
+                   CtxMul _ (Lit n) _
+                       | n ∈ [2,3,6] → "zent"
+                       | otherwise   → "gent"
+                   _                 → "zent"
+      )
+    ]
diff --git a/src/Text/Numeral/Language/EN.hs b/src/Text/Numeral/Language/EN.hs
--- a/src/Text/Numeral/Language/EN.hs
+++ b/src/Text/Numeral/Language/EN.hs
@@ -1,8 +1,8 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
 
 {-|
 [@ISO639-1@]        en
@@ -17,14 +17,23 @@
 -}
 
 module Text.Numeral.Language.EN
-    ( uk_cardinal
-    , ukPelletier_cardinal
+    ( -- * Language entries
+      gb_entry
+    , us_entry
+      -- * Conversions
+    , gb_cardinal
+    , gb_ordinal
+    , gbPelletier_cardinal
     , us_cardinal
+    , us_ordinal
+      -- * Structure
     , shortScaleStruct
-    , longScaleStruct
     , pelletierScaleStruct
+      -- * Bounds
+    , bounds
     ) where
 
+
 --------------------------------------------------------------------------------
 -- Imports
 --------------------------------------------------------------------------------
@@ -32,60 +41,93 @@
 import "base" Data.Bool     ( otherwise )
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
 import "base" Data.Ord      ( (<) )
-import "base" Data.String   ( IsString )
-import "base" Prelude       ( Integral, (-), Integer )
-import "base-unicode-symbols" Data.Function.Unicode ( (∘) ) 
+import "base" Prelude       ( (+), (-), div, subtract, negate, (^), error, Integral )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Prelude.Unicode ( ℤ, (⋅) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
-import qualified "numerals-base" Text.Numeral.BigNum as BN ( rule, scaleRepr, pelletierRepr )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum as BN
+import qualified "this" Text.Numeral.Exp    as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- EN
 --------------------------------------------------------------------------------
 
-uk_cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s
-uk_cardinal = render uk_cardinalRepr' ∘ shortScaleStruct
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "en"
+    , entIso639_2    = ["eng"]
+    , entIso639_3    = Just "eng"
+    , entNativeNames = ["English"]
+    , entEnglishName = Just "English"
+    }
 
-ukPelletier_cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s)
-                     ⇒ α → Maybe s
-ukPelletier_cardinal = render uk_cardinalRepr' { reprScale = pelletierRepr }
-                     ∘ pelletierScaleStruct
+gb_entry ∷ Entry
+gb_entry = entry
+    { entVariant  = Just "en-GB"
+    , entCardinal = Just Conversion
+                    { toNumeral   = gb_cardinal
+                    , toStructure = shortScaleStruct
+                    }
+    , entOrdinal  = Just Conversion
+                    { toNumeral   = gb_ordinal
+                    , toStructure = shortScaleStruct
+                    }
+    }
+
+us_entry ∷ Entry
+us_entry = entry
+    { entVariant  = Just "en-US"
+    , entCardinal = Just Conversion
+                    { toNumeral   = us_cardinal
+                    , toStructure = shortScaleStruct
+                    }
+    , entOrdinal  = Just Conversion
+                    { toNumeral   = us_ordinal
+                    , toStructure = shortScaleStruct
+                    }
+    }
+
+gb_cardinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+gb_cardinal inf = render (cardinalRepr "minus " gb_add) inf ∘ shortScaleStruct
+
+gb_ordinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+gb_ordinal inf = render (ordinalRepr gb_add) inf ∘ shortScaleStruct
+
+gbPelletier_cardinal ∷ (Inflection i, Integral α, E.Scale α)
+                     ⇒ i → α → Maybe Text
+gbPelletier_cardinal inf = render (cardinalRepr "minus " gb_add) { reprScale = pelletierRepr } inf
+                         ∘ pelletierScaleStruct
   where
-    pelletierRepr = BN.pelletierRepr "illion"  "illion"
-                                     "illiard" "illiard"
+    pelletierRepr = BN.pelletierRepr (\_ _ → "illion")
+                                     (\_ _ → "illiard")
                                      []
 
-us_cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s
-us_cardinal = render (cardinalRepr (⊞)) ∘ shortScaleStruct
-  where
-    ((_ `Mul` Lit 10) ⊞ _) _ = "-"
-    ((_ `Mul` _     ) ⊞ _) _ = " "
-    (_                ⊞ _) _ = ""
+us_cardinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+us_cardinal inf = render (cardinalRepr "negative " us_add) inf ∘ shortScaleStruct
 
-shortScaleStruct ∷ ( Integral α, C.Scale α
-                   , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β
+us_ordinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+us_ordinal inf = render (ordinalRepr us_add) inf ∘ shortScaleStruct
+
+shortScaleStruct ∷ ( Integral α, E.Scale α
+                   , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
                    )
                  ⇒ α → β
 shortScaleStruct = pos $ fix $ rule `combine` shortScale1 R L BN.rule
 
-longScaleStruct ∷ ( Integral α, C.Scale α
-                  , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β
-                  )
-                ⇒ α → β
-longScaleStruct = pos $ fix $ rule `combine` longScale1 R L BN.rule
-
-pelletierScaleStruct ∷ ( Integral α, C.Scale α
-                       , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β
+pelletierScaleStruct ∷ ( Integral α, E.Scale α
+                       , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
                        )
                      ⇒ α → β
 pelletierScaleStruct = pos $ fix $ rule `combine` pelletierScale1 R L BN.rule
 
-rule ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ Rule α β
+rule ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ Rule α β
 rule = findRule (   0, lit       )
               [ (  13, add 10 L  )
               , (  20, mul 10 R L)
@@ -94,53 +136,131 @@
               ]
                 (dec 6 - 1)
 
-uk_cardinalRepr' ∷ (Monoid s, IsString s) ⇒ Repr s
-uk_cardinalRepr' = cardinalRepr (⊞)
-  where
-    ((_ `Mul` Lit 10) ⊞ _) _       = "-"
-    ((_ `Mul` _     ) ⊞ x) _
-        | eval x < (100 ∷ Integer) = " and "
-        | otherwise                = " "
-    (_                ⊞ _) _       = ""
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 30003 - 1 in (negate x, x)
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ (Exp → Exp → Ctx Exp → s) → Repr s
-cardinalRepr f =
+genericRepr ∷ (Exp i → Exp i → Ctx (Exp i) → Text) -- ^ Add representation.
+            → Repr i
+genericRepr f =
     defaultRepr
-    { reprValue = \n → M.lookup n syms
-    , reprScale = BN.scaleRepr "illion" "illion" []
-    , reprAdd   = Just f
+    { reprAdd   = Just f
     , reprMul   = Just (⊞)
-    , reprNeg   = Just $ \_ _ → "minus "
     }
     where
       (_ ⊞ Lit 10) _ = ""
       (_ ⊞ _     ) _ = " "
 
+eval ∷ Exp i → ℤ
+eval (Lit x)       = x
+eval (Add x y)     = eval x + eval y
+eval (Mul x y)     = eval x ⋅ eval y
+eval (Sub x y)     = subtract (eval x) (eval y)
+eval (Neg x)       = negate (eval x)
+eval (Frac n d)    = eval n `div` eval d
+eval (Scale b o r) = 10 ^ (eval r ⋅ b + o)
+eval (Dual x)      = eval x
+eval (Plural x)    = eval x
+eval (Inflection _ x) = eval x
+eval Unknown       = error "eval: unknown"
+
+
+gb_add ∷ Exp i → Exp i → Ctx (Exp i) → Text
+((_ `Mul` Lit 10) `gb_add` _) _ = "-"
+((_ `Mul` _     ) `gb_add` x) _
+    | eval x < (100 ∷ ℤ)        = " and "
+    | otherwise                 = " "
+(_                `gb_add` _) _ = ""
+
+us_add ∷ Exp i → Exp i → Ctx (Exp i) → Text
+((_ `Mul` Lit 10) `us_add` _) _ = "-"
+((_ `Mul` _     ) `us_add` _) _ = " "
+(_                `us_add` _) _ = ""
+
+cardinalRepr ∷ Text -- ^ Negative number prefix.
+             → (Exp i → Exp i → Ctx (Exp i) → Text)
+             → Repr i
+cardinalRepr neg f =
+    (genericRepr f)
+    { reprValue = \_ n → M.lookup n syms
+    , reprScale = BN.scaleRepr (\_ _ → "illion") []
+    , reprNeg   = Just $ \_ _ → neg
+    }
+  where
+    syms =
+        M.fromList
+        [ (0, const "zero")
+        , (1, const "one")
+        , (2, ten   "two"   "two"  "twen")
+        , (3, ten   "three" "thir" "thir")
+        , (4, ten   "four"  "four" "for")
+        , (5, ten   "five"  "fif"  "fif")
+        , (6, const "six")
+        , (7, const "seven")
+        , (8, ten   "eight" "eigh" "eigh")
+        , (9, const "nine")
+        , (10, \c → case c of
+                      CtxAdd _ (Lit _) _ → "teen"
+                      CtxMul R _       _ → "ty"
+                      _                  → "ten"
+          )
+        , (11,   const "eleven")
+        , (12,   const "twelve")
+        , (100,  const "hundred")
+        , (1000, const "thousand")
+        ]
+
+    ten ∷ s → s → s → Ctx (Exp i) → s
+    ten n a m = \c → case c of
+                       CtxAdd _ (Lit 10) _ → a
+                       CtxMul _ (Lit 10) _ → m
+                       _                   → n
+
+ordinalRepr ∷ (Exp i → Exp i → Ctx (Exp i) → Text) → Repr i
+ordinalRepr f = (genericRepr f)
+                { reprValue = \_ n → M.lookup n syms
+                , reprScale = BN.scaleRepr (BN.ordQuantityName "illion" "illionth"
+                                                               "illion" "illionth"
+                                           )
+                                           []
+                }
+    where
       syms =
           M.fromList
-          [ (0, const "zero")
-          , (1, const "one")
-          , (2, ten   "two"   "two"  "twen")
-          , (3, ten   "three" "thir" "thir")
-          , (4, ten   "four"  "four" "for")
-          , (5, ten   "five"  "fif"  "fif")
-          , (6, const "six")
-          , (7, const "seven")
-          , (8, ten   "eight" "eigh" "eigh")
-          , (9, const "nine")
+          [ (0, const "zeroth")
+          , (1, \c → case c of
+                       _ | isOutside R c → "first"
+                         | otherwise     → "one"
+            )
+          , (2, ten   "second" "two"   "two"  "twen")
+          , (3, ten   "third"  "three" "thir" "thir")
+          , (4, ten   "fourth" "four"  "four" "for")
+          , (5, ten   "fifth"  "five"  "fif"  "fif")
+          , (6, \c → if isOutside R c then "sixth"   else "six")
+          , (7, \c → if isOutside R c then "seventh" else "seven")
+          , (8, ten   "eighth" "eight" "eigh" "eigh")
+          , (9, \c → if isOutside R c then "ninth"   else "nine")
           , (10, \c → case c of
-                        CtxAdd _ (Lit _) _ → "teen"
-                        CtxMul R _       _ → "ty"
-                        _                  → "ten"
+                        CtxAdd _ (Lit _) _ | isOutside R c → "teenth"
+                                           | otherwise     → "teen"
+                        CtxMul R _       _ | isOutside R c → "tieth"
+                                           | otherwise     → "ty"
+                        _                  | isOutside R c → "tenth"
+                                           | otherwise     → "ten"
             )
-          , (11,   const "eleven")
-          , (12,   const "twelve")
-          , (100,  const "hundred")
-          , (1000, const "thousand")
+          , (11,   \c → if isOutside R c then "eleventh"   else "eleven")
+          , (12,   \c → if isOutside R c then "twelfth"    else "twelf")
+          , (100,  \c → if isOutside R c then "hundreth"   else "hundred")
+          , (1000, \c → if isOutside R c then "thousandth" else "thousand")
           ]
 
-      ten ∷ s → s → s → Ctx Exp → s
-      ten n a m = \c → case c of
-                         CtxAdd _ (Lit 10) _ → a
-                         CtxMul _ (Lit 10) _ → m
-                         _                   → n
+      ten ∷ s -- ^ Ordinal form.
+          → s -- ^ Cardinal form; normal.
+          → s -- ^ Cardinal form; added to ten.
+          → s -- ^ Cardinal form; multiplied with ten.
+          → Ctx (Exp i)
+          → s
+      ten o n a m ctx = case ctx of
+                          _ | isOutside R ctx → o
+                          CtxAdd _ (Lit 10) _ → a
+                          CtxMul _ (Lit 10) _ → m
+                          _                   → n
diff --git a/src/Text/Numeral/Language/EO.hs b/src/Text/Numeral/Language/EO.hs
--- a/src/Text/Numeral/Language/EO.hs
+++ b/src/Text/Numeral/Language/EO.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        eo
@@ -17,8 +16,14 @@
 -}
 
 module Text.Numeral.Language.EO
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -28,23 +33,37 @@
 
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
 import "base" Prelude       ( Integral )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- EO
 --------------------------------------------------------------------------------
 
-cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "eo"
+    , entIso639_2    = ["epo"]
+    , entIso639_3    = Just "epo"
+    , entNativeNames = ["Esperanto"]
+    , entEnglishName = Just "Esperanto"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ α → β
 struct = checkPos
        $ fix
        $ findRule (  0, lit            )
@@ -53,9 +72,12 @@
                 ]
                   1000
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (0, 1000)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprAdd   = Just $ \_ _ _ → " "
                , reprMul   = Just $ \_ _ _ → ""
                }
diff --git a/src/Text/Numeral/Language/ES.hs b/src/Text/Numeral/Language/ES.hs
--- a/src/Text/Numeral/Language/ES.hs
+++ b/src/Text/Numeral/Language/ES.hs
@@ -1,8 +1,8 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        es
@@ -17,47 +17,66 @@
 -}
 
 module Text.Numeral.Language.ES
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 -------------------------------------------------------------------------------
 -- Imports
 -------------------------------------------------------------------------------
 
+import "base" Data.Bool     ( otherwise )
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
 import "base" Data.Ord      ( (<) )
-import "base" Data.String   ( IsString )
-import "base" Prelude       ( Integral, (-), Integer )
+import "base" Prelude       ( (-), negate, Integral )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Prelude.Unicode       ( ℤ )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.BigNum      as BN
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum  as BN
+import qualified "this" Text.Numeral.Exp     as E
+import qualified "this" Text.Numeral.Grammar as G
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 -------------------------------------------------------------------------------
 -- ES
 -------------------------------------------------------------------------------
 
--- Sources:
---   http://www.sf.airnet.ne.jp/~ts/language/number/spanish.html
---   http://spanish.about.com/cs/forbeginners/a/cardinalnum_beg.htm
---   http://www.learn-spanish-help.com/count-in-spanish.html
---   http://www.donquijote.org/spanishlanguage/numbers/numbers1.asp
---   http://en.wiktionary.org/wiki/Appendix:Spanish_numerals
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "es"
+    , entIso639_2    = ["spa"]
+    , entIso639_3    = Just "spa"
+    , entNativeNames = ["Español"]
+    , entEnglishName = Just "Spanish"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ ( G.Feminine i, G.Masculine i
+           , Integral α, E.Scale α
+           )
+         ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
 
-struct ∷ ( Integral α, C.Scale α
-         , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β
+struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
+         , E.Inflection β, G.Masculine (E.Inf β)
          )
        ⇒ α → β
-struct = pos (fix $ rule `combine` longScale R L BN.rule)
+struct = pos $ fix $ rule `combine` longScale1_es
     where
       rule = findRule (   0, lit       )
                     [ (  11, add 10 L  )
@@ -70,9 +89,25 @@
                     ]
                     (dec 6 - 1)
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+-- | Like 'longScale1' with the difference that all scale elements are
+-- masculine.
+longScale1_es ∷ ( Integral α, E.Scale α
+                , E.Unknown β, E.Lit β, E.Add β, E.Mul β, E.Scale β
+                , E.Inflection β, G.Masculine (E.Inf β)
+                )
+              ⇒ Rule α β
+longScale1_es = mulScale1_es 6 0 R L BN.rule
+    where
+      mulScale1_es = mulScale_ $ \f m s _ → masculineMul (f m) s
+      masculineMul x y = E.inflection (G.masculine) $ E.mul x y
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 60000 - 1 in (negate x, x)
+
+cardinalRepr ∷ ( G.Feminine i, G.Masculine i)
+             ⇒ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \inf n → M.lookup n (syms inf)
                , reprScale = longScaleRepr
                , reprAdd   = Just (⊞)
                , reprMul   = Just (⊡)
@@ -88,12 +123,16 @@
       (_ ⊡ Lit n) _ | n < 1000 = ""
       (_ ⊡ _    ) _            = " "
 
-      syms =
+      syms inf =
           M.fromList
           [ (0, const "cero")
           , (1, \c → case c of
-                       CtxAdd _ (Lit 10)  _ → "on"
-                       _                    → "uno"
+                       CtxAdd _ (Lit 10)  _    → "on"
+                       CtxAdd _ (Lit 20)  _
+                           | G.isMasculine inf → "ún"
+                       _   | G.isFeminine  inf → "una"
+                           | G.isMasculine inf → "un"
+                           | otherwise         → "uno"
             )
           , (2, \c → case c of
                        CtxAdd _ (Lit 10)  _ → "do"
@@ -148,20 +187,21 @@
                         _                   → "veinte"
             )
           , (100, \c → case c of
-                         CtxEmpty           → "cien"
-                         CtxAdd {}          → "ciento"
-                         CtxMul _ (Lit 5) _ → "ientos"
-                         CtxMul L _       _ → "cien"
-                         _                  → "cientos"
+                         CtxEmpty             → "cien"
+                         CtxAdd {}            → "ciento"
+                         CtxMul _ (Lit 5) _
+                           | G.isFeminine inf → "ientas"
+                           | otherwise        → "ientos"
+                         CtxMul L _       _   → "cien"
+                         _ | G.isFeminine inf → "cientas"
+                           | otherwise        → "cientos"
             )
           , (1000, const "mil")
           ]
 
-longScaleRepr ∷ (IsString s, Monoid s)
-              ⇒ Integer → Integer → Exp → Ctx Exp → Maybe s
+longScaleRepr ∷ i → ℤ → ℤ → (Exp i) → Ctx (Exp i) → Maybe Text
 longScaleRepr =
-    BN.scaleRepr "illón" "illones"
+    BN.scaleRepr (BN.quantityName "illón" "illones")
                  [ (4, BN.forms "cuatr" "cuator" "cuator" "cuatra" "cuatri")
                  , (9, BN.forms "non"   "noven"  "noven"  "nona"   "non")
                  ]
-
diff --git a/src/Text/Numeral/Language/Entries.hs b/src/Text/Numeral/Language/Entries.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/Entries.hs
@@ -0,0 +1,117 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+module Text.Numeral.Language.Entries ( entries ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "this" Text.Numeral.Entry ( Entry(..) )
+import qualified "this" Text.Numeral.Language.AF  as AF
+import qualified "this" Text.Numeral.Language.AMP as AMP
+import qualified "this" Text.Numeral.Language.BG  as BG
+import qualified "this" Text.Numeral.Language.CHN as CHN
+import qualified "this" Text.Numeral.Language.CHR as CHR
+import qualified "this" Text.Numeral.Language.CLM as CLM
+import qualified "this" Text.Numeral.Language.CS  as CS
+-- import qualified "this" Text.Numeral.Language.CY  as CY
+-- import qualified "this" Text.Numeral.Language.DA  as DA
+import qualified "this" Text.Numeral.Language.DE  as DE
+import qualified "this" Text.Numeral.Language.EN  as EN
+import qualified "this" Text.Numeral.Language.EO  as EO
+import qualified "this" Text.Numeral.Language.ES  as ES
+-- import qualified "this" Text.Numeral.Language.ET  as ET
+import qualified "this" Text.Numeral.Language.FI  as FI
+import qualified "this" Text.Numeral.Language.FR  as FR
+import qualified "this" Text.Numeral.Language.FUR as FUR
+import qualified "this" Text.Numeral.Language.GSW as GSW
+import qualified "this" Text.Numeral.Language.GV  as GV
+import qualified "this" Text.Numeral.Language.HE  as HE
+import qualified "this" Text.Numeral.Language.HOP as HOP
+-- import qualified "this" Text.Numeral.Language.HR  as HR
+-- import qualified "this" Text.Numeral.Language.HU  as HU
+import qualified "this" Text.Numeral.Language.IT  as IT
+import qualified "this" Text.Numeral.Language.JA  as JA
+import qualified "this" Text.Numeral.Language.LA  as LA
+import qualified "this" Text.Numeral.Language.LLD as LLD
+import qualified "this" Text.Numeral.Language.MG  as MG
+import qualified "this" Text.Numeral.Language.NL  as NL
+import qualified "this" Text.Numeral.Language.NO  as NO
+import qualified "this" Text.Numeral.Language.NQM as NQM
+import qualified "this" Text.Numeral.Language.OJ  as OJ
+-- import qualified "this" Text.Numeral.Language.PAA as PAA
+import qualified "this" Text.Numeral.Language.PDC as PDC
+import qualified "this" Text.Numeral.Language.PL  as PL
+import qualified "this" Text.Numeral.Language.PT  as PT
+-- import qualified "this" Text.Numeral.Language.RO  as RO
+import qualified "this" Text.Numeral.Language.RU  as RU
+import qualified "this" Text.Numeral.Language.SCO as SCO
+import qualified "this" Text.Numeral.Language.SV  as SV
+import qualified "this" Text.Numeral.Language.TR  as TR
+import qualified "this" Text.Numeral.Language.WO  as WO
+import qualified "this" Text.Numeral.Language.YOR as YOR
+import qualified "this" Text.Numeral.Language.ZH  as ZH
+
+
+--------------------------------------------------------------------------------
+-- Language entries
+--------------------------------------------------------------------------------
+
+entries ∷ [Entry]
+entries =
+  [ AF.entry
+  , AMP.entry
+  , BG.entry
+  , CHN.entry
+  , CHR.entry
+  , CLM.entry
+  , CS.entry
+--, CY.entry
+--, DA.entry
+  , DE.entry
+  , EN.gb_entry
+  , EN.us_entry
+  , EO.entry
+  , ES.entry
+--, ET.entry
+  , FI.entry
+  , FR.entry
+  , FUR.entry
+  , GSW.entry
+  , GV.entry
+  , HE.entry
+  , HOP.entry
+--, HR.entry
+--, HU.entry
+  , IT.entry
+  , JA.daiji_entry
+  , JA.kanji_entry
+  , JA.on'yomi_entry
+  , JA.preferred_entry
+  , LA.entry
+  , LLD.entry
+  , MG.entry
+  , NL.entry
+  , NO.entry
+  , NQM.entry
+  , OJ.entry
+--, PAA.entry
+  , PDC.entry
+  , PL.entry
+  , PT.entry
+--, RO.entry
+  , RU.entry
+  , SCO.entry
+  , SV.entry
+  , TR.entry
+  , WO.entry
+  , YOR.entry
+  , ZH.finance_simpl_entry
+  , ZH.finance_trad_entry
+  , ZH.pinyin_entry
+  , ZH.simpl_entry
+  , ZH.trad_entry
+  ]
diff --git a/src/Text/Numeral/Language/FI.hs b/src/Text/Numeral/Language/FI.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/FI.hs
@@ -0,0 +1,960 @@
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        fi
+
+[@ISO639-2B@]       fin
+
+[@ISO639-3@]        fin
+
+[@Native name@]     suomi
+
+[@English name@]    Finnish
+-}
+
+module Text.Numeral.Language.FI
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+    , ordinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    ) where
+
+
+-------------------------------------------------------------------------------
+-- Imports
+-------------------------------------------------------------------------------
+
+import "base" Data.Bool     ( otherwise )
+import "base" Data.Function ( ($), fix, flip )
+import "base" Data.Maybe    ( Maybe(Just) )
+import "base" Prelude       ( Num, Integral, (-), negate, divMod )
+import "base-unicode-symbols" Data.Bool.Unicode     ( (∧) )
+import "base-unicode-symbols" Data.Eq.Unicode       ( (≡) )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Data.Ord.Unicode      ( (≤) )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum  as BN
+import qualified "this" Text.Numeral.Exp     as E
+import qualified "this" Text.Numeral.Grammar as G
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
+
+
+-------------------------------------------------------------------------------
+-- FI
+-------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "fi"
+    , entIso639_2    = ["fin"]
+    , entIso639_3    = Just "fin"
+    , entNativeNames = ["suomi"]
+    , entEnglishName = Just "Finnish"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    , entOrdinal     = Just Conversion
+                       { toNumeral   = ordinal
+                       , toStructure = struct
+                       }
+    }
+
+cardinal ∷ ( G.Singular i, G.Plural i
+           , G.Abessive i
+           , G.Accusative i
+           , G.Comitative i
+           , G.Delative i
+           , G.Distributive i
+           , G.DistributiveTemporal i
+           , G.Essive i
+           , G.Genitive i
+           , G.Instructive i
+           , G.Lative i
+           , G.LocativeInessive i
+           , G.LocativeElative i
+           , G.LocativeIllative i
+           , G.LocativeAdessive i
+           , G.LocativeAblative i
+           , G.LocativeAllative i
+           , G.Multiplicative i
+           , G.Nominative i
+           , G.Partitive i
+           , G.Sublative i
+           , G.SuperEssive i
+           , G.Translative i
+           , Integral α, E.Scale α
+           )
+         ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+ordinal ∷ ( G.Singular i, G.Plural i
+          , G.Abessive i
+          , G.Accusative i
+          , G.Comitative i
+          , G.Delative i
+          , G.Distributive i
+          , G.DistributiveTemporal i
+          , G.Essive i
+          , G.Genitive i
+          , G.Instructive i
+          , G.Lative i
+          , G.LocativeInessive i
+          , G.LocativeElative i
+          , G.LocativeIllative i
+          , G.LocativeAdessive i
+          , G.LocativeAblative i
+          , G.LocativeAllative i
+          , G.Multiplicative i
+          , G.Nominative i
+          , G.Partitive i
+          , G.Sublative i
+          , G.SuperEssive i
+          , G.Translative i
+          , Integral α, E.Scale α
+          )
+        ⇒ i → α → Maybe Text
+ordinal inf = ordinalRepr inf ∘ struct
+
+struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Add β, E.Mul β
+         , E.Inflection β, E.Scale β
+         , G.Singular   (E.Inf β)
+         , G.Nominative (E.Inf β)
+         , G.Accusative (E.Inf β)
+         , G.Partitive  (E.Inf β)
+         )
+       ⇒ α → β
+struct = fix $ rule `combine` pelletierScale R L BN.rule
+    where
+      rule = findRule (   0, lit)
+                    [ (  11, add 10 L)
+                    , (  20, fi_mul 10)
+                    , ( 100, step  100   10 R L)
+                    , (1000, step 1000 1000 R L)
+                    ]
+                      (dec 6 - 1)
+
+-- | Like the normal 'mul' rule with the difference that the value
+-- that is multiplied is changed to the partitive case.
+fi_mul ∷ ( Integral α
+         , E.Add β, E.Mul β, E.Inflection β
+         , G.Singular   (E.Inf β)
+         , G.Nominative (E.Inf β)
+         , G.Accusative (E.Inf β)
+         , G.Partitive  (E.Inf β)
+         )
+       ⇒ α → Rule α β
+fi_mul val =
+    \f n → let (m, a) = n `divMod` val
+               mval = E.mul (f m) (E.inflection toPartitive $ f val)
+           in if a ≡ 0
+              then mval
+              else (flip E.add) (f a) mval
+  where
+    toPartitive ∷ (G.Singular i, G.Nominative i, G.Accusative i, G.Partitive i)
+                ⇒ i → i
+    toPartitive inf | G.isSingular inf ∧ G.isNominative inf = G.partitive inf
+                    | G.isSingular inf ∧ G.isAccusative inf = G.partitive inf
+                    | otherwise = inf
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 15 - 1 in (negate x, x)
+
+cardinalRepr ∷ ( G.Singular i, G.Plural i
+               , G.Abessive i
+               , G.Accusative i
+               , G.Comitative i
+               , G.Delative i
+               , G.Distributive i
+               , G.DistributiveTemporal i
+               , G.Essive i
+               , G.Genitive i
+               , G.Instructive i
+               , G.Lative i
+               , G.LocativeInessive i
+               , G.LocativeElative i
+               , G.LocativeIllative i
+               , G.LocativeAdessive i
+               , G.LocativeAblative i
+               , G.LocativeAllative i
+               , G.Multiplicative i
+               , G.Nominative i
+               , G.Partitive i
+               , G.Sublative i
+               , G.SuperEssive i
+               , G.Translative i
+               )
+             ⇒ i → Exp i → Maybe Text
+cardinalRepr = render defaultRepr
+               { reprValue = \inf n → M.lookup n (syms inf)
+               , reprScale = BN.pelletierRepr
+                               (BN.quantityName "iljoona" "iljoonaa")
+                               (BN.quantityName "iljardi" "iljardia")
+                               []
+               , reprAdd   = Just $ \_ _ _ → ""
+               , reprMul   = Just $ \_ _ _ → ""
+               }
+    where
+      syms inf =
+          M.fromList
+          [ (0, \c → infForms inf c
+                              -- singular
+                              "nolla"    {- nom -} "nolla"    {- acc -}
+                              "nollan"   {- gen -} "nollaa"   {- ptv -}
+                              "nollana"  {- ess -} "nollaksi" {- transl -}
+                              "nollassa" {- ine -} "nollasta" {- ela -}
+                              "nollaan"  {- ill -} "nollalla" {- ade -}
+                              "nollalta" {- abl -} "nollalle" {- all -}
+                              "nollatta" {- abe -}
+                              "?"        {- other -}
+                              -- plural
+                              "nollat"   {- nom -} "nollat"   {- acc -}
+                              "nollien"  {- gen -} "nollia"   {- ptv -}
+                              "nollina"  {- ess -} "nolliksi" {- transl -}
+                              "nollissa" {- ine -} "nollista" {- ela -}
+                              "nolliin"  {- ill -} "nollilla" {- ade -}
+                              "nollilta" {- abl -} "nollille" {- all -}
+                              "nollitta" {- abe -} "nolline"  {- com -}
+                              "nollin"   {- instr -}
+                              "?"        {- other -}
+            )
+         , (1, \c → infForms inf c
+                             -- singular
+                             "yksi"     {- nom -} "yksi"     {- acc -}
+                             "yhden"    {- gen -} "yhtä"     {- ptv -}
+                             "yhtenä"   {- ess -} "yhdeksi"  {- transl -}
+                             "yhdessä"  {- ine -} "yhdestä"  {- ela -}
+                             "yhteen"   {- ill -} "yhdellä"  {- ade -}
+                             "yhdeltä"  {- abl -} "yhdelle"  {- all -}
+                             "yhdettä"  {- abe -}
+                             (case inf of
+                                _ | G.isSuperEssive    inf → "yhtäällä"
+                                  | G.isDelative       inf → "yhtäältä"
+                                  | G.isSublative      inf → "yhtäälle"
+                                  | G.isLative         inf → "yhä"
+                                  | G.isMultiplicative inf → "yhdesti"
+                                  | otherwise              → "?"
+                             )
+                             -- plural
+                             "yhdet"    {- nom -} "yhdet"    {- acc -}
+                             "yksien"   {- gen -} "yksiä"    {- ptv -}
+                             "yksinä"   {- ess -} "yksiksi"  {- transl -}
+                             "yksissä"  {- ine -} "yksistä"  {- ela -}
+                             "yksiin"   {- ill -} "yksillä"  {- ade -}
+                             "yksiltä"  {- abl -} "yksille"  {- all -}
+                             "yksittä"  {- abe -} "yksine"   {- com -}
+                             "yksin"    {- instr -}
+                             (case inf of
+                                _ | G.isDistributive inf → "yksittäin"
+                                  | otherwise            → "?"
+                             )
+           )
+          , (2, \c → infForms inf c
+                              -- singular
+                              "kaksi"    {- nom -} "kaksi"    {- acc -}
+                              "kahden"   {- gen -} "kahta"    {- ptv -}
+                              "kahtena"  {- ess -} "kahdeksi" {- transl -}
+                              "kahdessa" {- ine -} "kahdesta" {- ela -}
+                              "kahteen"  {- ill -} "kahdella" {- ade -}
+                              "kahdelta" {- abl -} "kahdelle" {- all -}
+                              "kahdetta" {- abe -}
+                              (case inf of
+                                 _ | G.isInstructive    inf → "kahden"
+                                   | G.isSuperEssive    inf → "kahtaalla"
+                                   | G.isDelative       inf → "kahtaalta"
+                                   | G.isSublative      inf → "kahtaalle"
+                                   | G.isLative         inf → "kahtia"
+                                   | G.isMultiplicative inf → "kahdesti"
+                                   | otherwise              → "?"
+                              )
+                              -- plural
+                              "kahdet"   {- nom -} "kahdet"   {- acc -}
+                              "kaksien"  {- gen -} "kaksia"   {- ptv -}
+                              "kaksina"  {- ess -} "kaksiksi" {- transl -}
+                              "kaksissa" {- ine -} "kaksista" {- ela -}
+                              "kaksiin"  {- ill -} "kaksilla" {- ade -}
+                              "kaksilta" {- abl -} "kaksille" {- all -}
+                              "kaksitta" {- abe -} "kaksine"  {- com -}
+                              "kaksin"   {- instr -}
+                              (case inf of
+                                 _ | G.isDistributive inf → "kaksittain"
+                                   | otherwise            → "?"
+                              )
+            )
+          , (3, \c → infForms inf c
+                              -- singular
+                              "kolme"    {- nom -} "kolme"    {- acc -}
+                              "kolmen"   {- gen -} "kolmea"   {- ptv -}
+                              "kolmena"  {- ess -} "kolmeksi" {- transl -}
+                              "kolmessa" {- ine -} "kolmesta" {- ela -}
+                              "kolmeen"  {- ill -} "kolmella" {- ade -}
+                              "kolmelta" {- abl -} "kolmelle" {- all -}
+                              "kolmetta" {- abe -}
+                              (case inf of
+                                 _ | G.isInstructive    inf → "kolmen"
+                                   | G.isLative         inf → "kolmia"
+                                   | G.isMultiplicative inf → "kolmesti"
+                                   | otherwise              → "?"
+                              )
+                              -- plural
+                              "kolmet"   {- nom -} "kolmet"   {- acc -}
+                              "kolmien"  {- gen -} "kolmia"   {- ptv -}
+                              "kolmina"  {- ess -} "kolmiksi" {- transl -}
+                              "kolmissa" {- ine -} "kolmista" {- ela -}
+                              "kolmiin"  {- ill -} "kolmilla" {- ade -}
+                              "kolmilta" {- abl -} "kolmille" {- all -}
+                              "kolmitta" {- abe -} "kolmine"  {- com -}
+                              "kolmin"   {- instr -}
+                              (case inf of
+                                 _ | G.isDistributive         inf → "kolmittain"
+                                   | G.isDistributiveTemporal inf → "kolmisin"
+                                   | otherwise                    → "?"
+                              )
+            )
+          , (4, \c → infForms inf c
+                              -- singular
+                              "neljä"    {- nom -} "neljä"    {- acc -}
+                              "neljän"   {- gen -} "neljää"   {- ptv -}
+                              "neljänä"  {- ess -} "neljäksi" {- transl -}
+                              "neljässä" {- ine -} "neljästä" {- ela -}
+                              "neljään"  {- ill -} "neljällä" {- ade -}
+                              "neljältä" {- abl -} "neljälle" {- all -}
+                              "neljättä" {- abe -}
+                              "?"        {- other -}
+                              -- plural
+                              "neljät"   {- nom -} "neljät"   {- acc -}
+                              "neljien"  {- gen -} "neljiä"   {- ptv -}
+                              "neljinä"  {- ess -} "neljiksi" {- transl -}
+                              "neljissä" {- ine -} "neljistä" {- ela -}
+                              "neljiin"  {- ill -} "neljillä" {- ade -}
+                              "neljiltä" {- abl -} "neljille" {- all -}
+                              "neljittä" {- abe -} "neljine"  {- com -}
+                              "neljin"   {- instr -}
+                              "?"        {- other -}
+            )
+          , (5, \c → infForms inf c
+                              -- singular
+                              "viisi"    {- nom -} "viisi"    {- acc -}
+                              "viiden"   {- gen -} "viittä"   {- ptv -}
+                              "viitenä"  {- ess -} "viideksi" {- transl -}
+                              "viidessä" {- ine -} "viidestä" {- ela -}
+                              "viiteen"  {- ill -} "viidellä" {- ade -}
+                              "viideltä" {- abl -} "viidelle" {- all -}
+                              "viidettä" {- abe -}
+                              "?"        {- other -}
+                              -- plural
+                              "viidet"   {- nom -} "viidet"   {- acc -}
+                              "viisien"  {- gen -} "viisiä"   {- ptv -}
+                              "viisinä"  {- ess -} "viisiksi" {- transl -}
+                              "viisissä" {- ine -} "viisistä" {- ela -}
+                              "viisiin"  {- ill -} "viisillä" {- ade -}
+                              "viisiltä" {- abl -} "viisille" {- all -}
+                              "viisittä" {- abe -} "viisine"  {- com -}
+                              "viisin"   {- instr -}
+                              "?"        {- other -}
+            )
+          , (6, \c → infForms inf c
+                              -- singular
+                              "kuusi"    {- nom -} "kuusi"    {- acc -}
+                              "kuuden"   {- gen -} "kuutta"   {- ptv -}
+                              "kuutena"  {- ess -} "kuudeksi" {- transl -}
+                              "kuudessa" {- ine -} "kuudesta" {- ela -}
+                              "kuuteen"  {- ill -} "kuudella" {- ade -}
+                              "kuudelta" {- abl -} "kuudelle" {- all -}
+                              "kuudetta" {- abe -}
+                              "?"        {- other -}
+                              -- plural
+                              "kuudet"   {- nom -} "kuudet"   {- acc -}
+                              "kuusien"  {- gen -} "kuusia"   {- ptv -}
+                              "kuusina"  {- ess -} "kuusiksi" {- transl -}
+                              "kuusissa" {- ine -} "kuusista" {- ela -}
+                              "kuusiin"  {- ill -} "kuusilla" {- ade -}
+                              "kuusilta" {- abl -} "kuusille" {- all -}
+                              "kuusitta" {- abe -} "kuusine"  {- com -}
+                              "kuusin"   {- instr -}
+                              "?"        {- other -}
+            )
+          , (7, \c → infForms inf c
+                              -- singular
+                              "seitsemän"   {- nom -} "seitsemän"   {- acc -}
+                              "seitsemän"   {- gen -} "seitsemää"   {- ptv -}
+                              "seitsemänä"  {- ess -} "seitsemäksi" {- transl -}
+                              "seitsemässä" {- ine -} "seitsemästä" {- ela -}
+                              "seitsemään"  {- ill -} "seitsemällä" {- ade -}
+                              "seitsemältä" {- abl -} "seitsemälle" {- all -}
+                              "seitsemättä" {- abe -}
+                              "?"           {- other -}
+                              -- plural
+                              "seitsemät"   {- nom -} "seitsemät"   {- acc -}
+                              "seitsemien"  {- gen -} "seitsemiä"   {- ptv -}
+                              "seitseminä"  {- ess -} "seitsemiksi" {- transl -}
+                              "seitsemissä" {- ine -} "seitsemistä" {- ela -}
+                              "seitsemiin"  {- ill -} "seitsemillä" {- ade -}
+                              "seitsemiltä" {- abl -} "seitsemille" {- all -}
+                              "seitsemittä" {- abe -} "seitsemine"  {- com -}
+                              "seitsemin"   {- instr -}
+                              "?"           {- other -}
+            )
+          , (8, \c → infForms inf c
+                              -- singular
+                              "kahdeksan"   {- nom -} "kahdeksan"   {- acc -}
+                              "kahdeksan"   {- gen -} "kahdeksaa"   {- ptv -}
+                              "kahdeksana"  {- ess -} "kahdeksaksi" {- transl -}
+                              "kahdeksassa" {- ine -} "kahdeksasta" {- ela -}
+                              "kahdeksaan"  {- ill -} "kahdeksalla" {- ade -}
+                              "kahdeksalta" {- abl -} "kahdeksalle" {- all -}
+                              "kahdeksatta" {- abe -}
+                              "?"           {- other -}
+                              -- plural
+                              "kahdeksat"   {- nom -} "kahdeksat"   {- acc -}
+                              "kahdeksien"  {- gen -} "kahdeksia"   {- ptv -}
+                              "kahdeksina"  {- ess -} "kahdeksiksi" {- transl -}
+                              "kahdeksissa" {- ine -} "kahdeksista" {- ela -}
+                              "kahdeksiin"  {- ill -} "kahdeksilla" {- ade -}
+                              "kahdeksilta" {- abl -} "kahdeksille" {- all -}
+                              "kahdeksitta" {- abe -} "kahdeksine"  {- com -}
+                              "kahdeksin"   {- instr -}
+                              "?"           {- other -}
+            )
+          , (9, \c → infForms inf c
+                              -- singular
+                              "yhdeksän"   {- nom -} "yhdeksän"   {- acc -}
+                              "yhdeksän"   {- gen -} "yhdeksää"   {- ptv -}
+                              "yhdeksänä"  {- ess -} "yhdeksäksi" {- transl -}
+                              "yhdeksässä" {- ine -} "yhdeksästä" {- ela -}
+                              "yhdeksään"  {- ill -} "yhdeksällä" {- ade -}
+                              "yhdeksältä" {- abl -} "yhdeksälle" {- all -}
+                              "yhdeksättä" {- abe -}
+                              "?"          {- other -}
+                              -- plural
+                              "yhdeksät"   {- nom -} "yhdeksät"   {- acc -}
+                              "yhdeksien"  {- gen -} "yhdeksiä"   {- ptv -}
+                              "yhdeksinä"  {- ess -} "yhdeksiksi" {- transl -}
+                              "yhdeksissä" {- ine -} "yhdeksistä" {- ela -}
+                              "yhdeksiin"  {- ill -} "yhdeksillä" {- ade -}
+                              "yhdeksiltä" {- abl -} "yhdeksille" {- all -}
+                              "yhdeksittä" {- abe -} "yhdeksine"  {- com -}
+                              "yhdeksin"   {- instr -}
+                              "?"          {- other -}
+            )
+
+          , (10, \c → case c of
+                        CtxAdd _ (Lit _) _ → "toista" -- singular partitive ordinal 2
+                        _ → infForms inf c
+                              -- singular
+                              "kymmenen"   {- nom -} "kymmenen"   {- acc -}
+                              "kymmenen"   {- gen -} "kymmentä"   {- ptv -}
+                              "kymmenenä"  {- ess -} "kymmeneksi" {- transl -}
+                              "kymmenessä" {- ine -} "kymmenestä" {- ela -}
+                              "kymmeneen"  {- ill -} "kymmenellä" {- ade -}
+                              "kymmeneltä" {- abl -} "kymmenelle" {- all -}
+                              "kymmenettä" {- abe -}
+                              "?"          {- other -}
+                              -- plural
+                              "kymmenet"   {- nom -} "kymmenet"   {- acc -}
+                              "kymmenien"  {- gen -} "kymmeniä"   {- ptv -}
+                              "kymmeninä"  {- ess -} "kymmeniksi" {- transl -}
+                              "kymmenissä" {- ine -} "kymmenistä" {- ela -}
+                              "kymmeniin"  {- ill -} "kymmenillä" {- ade -}
+                              "kymmeniltä" {- abl -} "kymmenille" {- all -}
+                              "kymmenittä" {- abe -} "kymmenine"  {- com -}
+                              "kymmenin"   {- instr -}
+                              "?"          {- other -}
+            )
+          , (100, \c → case c of
+                         CtxMul _ (Lit n) _
+                             | n ≤ 9        → "sataa"
+                         _ → infForms inf c
+                               -- singular
+                               "sata"    {- nom -} "sata"    {- acc -}
+                               "sadan"   {- gen -} "sataa"   {- ptv -}
+                               "satana"  {- ess -} "sadaksi" {- transl -}
+                               "sadassa" {- ine -} "sadasta" {- ela -}
+                               "sataan"  {- ill -} "sadalla" {- ade -}
+                               "sadalta" {- abl -} "sadalle" {- all -}
+                               "sadatta" {- abe -}
+                               "?"       {- other -}
+                               -- plural
+                               "sadat"    {- nom -} "sadat"    {- acc -}
+                               "satojen"  {- gen -} "satoja"   {- ptv -}
+                               "satoina"  {- ess -} "sadoiksi" {- transl -}
+                               "sadoissa" {- ine -} "sadoista" {- ela -}
+                               "satoihin" {- ill -} "sadoilla" {- ade -}
+                               "sadoilta" {- abl -} "sadoille" {- all -}
+                               "sadoitta" {- abe -} "satoine"  {- com -}
+                               "sadoin"   {- instr -}
+                               "?"        {- other -}
+            )
+          , (1000, \c → case c of
+                          CtxMul {} → "tuhatta"
+                          _ → infForms inf c
+                                -- singular
+                                "tuhat"      {- nom -} "tuhat"      {- acc -}
+                                "tuhannen"   {- gen -} "tuhatta"    {- ptv -}
+                                "tuhantena"  {- ess -} "tuhanneksi" {- transl -}
+                                "tuhannessa" {- ine -} "tuhannesta" {- ela -}
+                                "tuhanteen"  {- ill -} "tuhannella" {- ade -}
+                                "tuhannelta" {- abl -} "tuhannelle" {- all -}
+                                "tuhannetta" {- abe -}
+                                "?"          {- other -}
+                                -- plural
+                                "tuhannet"   {- nom -} "tuhannet"   {- acc -}
+                                "tuhansien"  {- gen -} "tuhansia"   {- ptv -}
+                                "tuhansina"  {- ess -} "tuhansiksi" {- transl -}
+                                "tuhansissa" {- ine -} "tuhansista" {- ela -}
+                                "tuhansiin"  {- ill -} "tuhansilla" {- ade -}
+                                "tuhansilta" {- abl -} "tuhansille" {- all -}
+                                "tuhansitta" {- abe -} "tuhansine"  {- com -}
+                                "tuhansin"   {- instr -}
+                                "?"          {- other -}
+            )
+          ]
+
+ordinalRepr ∷ ( G.Singular i, G.Plural i
+              , G.Abessive i
+              , G.Accusative i
+              , G.Comitative i
+              , G.Delative i
+              , G.Distributive i
+              , G.DistributiveTemporal i
+              , G.Essive i
+              , G.Genitive i
+              , G.Instructive i
+              , G.Lative i
+              , G.LocativeInessive i
+              , G.LocativeElative i
+              , G.LocativeIllative i
+              , G.LocativeAdessive i
+              , G.LocativeAblative i
+              , G.LocativeAllative i
+              , G.Multiplicative i
+              , G.Nominative i
+              , G.Partitive i
+              , G.Sublative i
+              , G.SuperEssive i
+              , G.Translative i
+              )
+             ⇒ i → Exp i → Maybe Text
+ordinalRepr = render defaultRepr
+              { reprValue = \inf n → M.lookup n (syms inf)
+              , reprScale = BN.pelletierRepr
+                              (BN.quantityName "iljoona" "iljoonaa")
+                              (BN.quantityName "iljardi" "iljardia")
+                              []
+              , reprAdd   = Just $ \_ _ _ → ""
+              , reprMul   = Just $ \_ _ _ → ""
+              }
+    where
+      syms inf =
+          M.fromList
+          [ (0, \c → infForms inf c
+                              -- singular
+                              "nollas"      {- nom -} "nollas"      {- acc -}
+                              "nollannen"   {- gen -} "nollatta"    {- ptv -}
+                              "nollantena"  {- ess -} "nollanneksi" {- transl -}
+                              "nollannessa" {- ine -} "nollannesta" {- ela -}
+                              "nollanteen"  {- ill -} "nollannella" {- ade -}
+                              "nollannelta" {- abl -} "nollannelle" {- all -}
+                              "nollannetta" {- abe -}
+                              "?"           {- other -}
+                              -- plural
+                              "nollannet"   {- nom -} "nollannet"   {- acc -}
+                              "nollansien"  {- gen -} "nollansia"   {- ptv -}
+                              "nollansina"  {- ess -} "nollansiksi" {- transl -}
+                              "nollansissa" {- ine -} "nollansista" {- ela -}
+                              "nollansiin"  {- ill -} "nollansilla" {- ade -}
+                              "nollansilta" {- abl -} "nollansille" {- all -}
+                              "nollansitta" {- abe -} "nollansine"  {- com -}
+                              "nollansin"   {- instr -}
+                              "?"           {- other -}
+            )
+          , (1, \c → case c of
+                       CtxAdd _ (Lit 10) _ →
+                           infForms inf c
+                              -- singular
+                              "yhdes"      {- nom -} "yhdes"      {- acc -}
+                              "yhdennen"   {- gen -} "yhdettä"    {- ptv -}
+                              "yhdennessä" {- ess -} "yhdenneksi" {- transl -}
+                              "yhdennessä" {- ine -} "yhdennestä" {- ela -}
+                              "yhdenteen"  {- ill -} "yhdennellä" {- ade -}
+                              "yhdenneltä" {- abl -} "yhdennelle" {- all -}
+                              "yhdennettä" {- abe -}
+                              "?"          {- other -}
+                              -- plural
+                              "yhdennet"   {- nom -} "yhdennet"   {- acc -}
+                              "yhdensien"  {- gen -} "yhdensiä"   {- ptv -}
+                              "yhdensinä"  {- ess -} "yhdensiksi" {- transl -}
+                              "yhdensissä" {- ine -} "yhdensistä" {- ela -}
+                              "yhdensiin"  {- ill -} "yhdensillä" {- ade -}
+                              "yhdensitlä" {- abl -} "yhdensiin"  {- all -}
+                              "yhdensittä" {- abe -} "yhdensine"  {- com -}
+                              "yhdensin"   {- instr -}
+                              "?"          {- other -}
+                       _ → infForms inf c
+                              -- singular
+                              "ensimmäinen"   {- nom -} "ensimmäinen"   {- acc -}
+                              "ensimmäisen"   {- gen -} "ensimmäistä"   {- ptv -}
+                              "ensimmmäisenä" {- ess -} "ensimmäiseksi" {- transl -}
+                              "ensimmäisessä" {- ine -} "ensimmäisestä" {- ela -}
+                              "ensimmäiseen"  {- ill -} "ensimmäisellä" {- ade -}
+                              "ensimmäiseltä" {- abl -} "ensimmäiselle" {- all -}
+                              "ensimmäisettä" {- abe -}
+                              "?"             {- other -}
+                              -- plural
+                              "ensimmäiset"   {- nom -} "ensimmäiset"   {- acc -}
+                              "ensimmäisten"  {- gen -} "ensimmäisiä"   {- ptv -}
+                              "ensimmäisinä"  {- ess -} "ensimmäisiksi" {- transl -}
+                              "ensimmäisissä" {- ine -} "ensimmäisistä" {- ela -}
+                              "ensimmäisiin"  {- ill -} "ensimmäisillä" {- ade -}
+                              "ensimmäisiltä" {- abl -} "ensimmäisille" {- all -}
+                              "ensimmäisittä" {- abe -} "ensimmäisine"  {- com -}
+                              "ensimmäisin"   {- instr -}
+                              "?"             {- other -}
+            )
+          , (2, \c → case c of
+                       CtxAdd _ (Lit 10) _ →
+                           infForms inf c
+                              -- singular
+                              "kahdes"      {- nom -} "kahdes"      {- acc -}
+                              "kahdennen"   {- gen -} "kahdetta"    {- ptv -}
+                              "kahdentena"  {- ess -} "kahdenneksi" {- transl -}
+                              "kahdennessa" {- ine -} "kahdennesta" {- ela -}
+                              "kahdenteen"  {- ill -} "kahdennella" {- ade -}
+                              "kahdennelta" {- abl -} "kahdennelle" {- all -}
+                              "kahdennetta" {- abe -}
+                              "?"           {- other -}
+                              -- plural
+                              "kahdennet"   {- nom -} "kahdennet"   {- acc -}
+                              "kahdensien"  {- gen -} "kahdensia"   {- ptv -}
+                              "kahdensina"  {- ess -} "kahdensiksi" {- transl -}
+                              "kahdensissa" {- ine -} "kahdensista" {- ela -}
+                              "kahdensiin"  {- ill -} "kahdensilla" {- ade -}
+                              "kahdensilta" {- abl -} "kahdensille" {- all -}
+                              "kahdensitta" {- abe -} "kahdensine"  {- com -}
+                              "kahdensin"   {- instr -}
+                              "?"           {- other -}
+                       _ → infForms inf c
+                              -- singular
+                              "toinen"   {- nom -} "toinen"   {- acc -}
+                              "toisen"   {- gen -} "toista"   {- ptv -}
+                              "toisena"  {- ess -} "toiseksi" {- transl -}
+                              "toisessa" {- ine -} "toisesta" {- ela -}
+                              "toiseen"  {- ill -} "toisella" {- ade -}
+                              "toiselta" {- abl -} "toiselle" {- all -}
+                              "toisetta" {- abe -}
+                              "?"        {- other -}
+                              -- plural
+                              "toiset"   {- nom -} "toiset"   {- acc -}
+                              "toisten"  {- gen -} "toisia"   {- ptv -}
+                              "toisina"  {- ess -} "toisiksi" {- transl -}
+                              "toisissa" {- ine -} "toisista" {- ela -}
+                              "toisiin"  {- ill -} "toisilla" {- ade -}
+                              "toisilta" {- abl -} "toisille" {- all -}
+                              "toisitta" {- abe -} "toisine"  {- com -}
+                              "toisin"   {- instr -}
+                              "?"        {- other -}
+            )
+          , (3, \c → infForms inf c
+                              -- singular
+                              "kolmas"      {- nom -} "kolmas"      {- acc -}
+                              "kolmannen"   {- gen -} "kolmatta"    {- ptv -}
+                              "kolmantena"  {- ess -} "kolmanneksi" {- transl -}
+                              "kolmannessa" {- ine -} "kolmannesta" {- ela -}
+                              "kolmanteen"  {- ill -} "kolmannella" {- ade -}
+                              "kolmannelta" {- abl -} "kolmannelle" {- all -}
+                              "kolmannetta" {- abe -}
+                              "?"           {- other -}
+                              -- plural
+                              "kolmannet"   {- nom -} "kolmannet"   {- acc -}
+                              "kolmansien"  {- gen -} "kolmansia"   {- ptv -}
+                              "kolmansina"  {- ess -} "kolmansiksi" {- transl -}
+                              "kolmansissa" {- ine -} "kolmansista" {- ela -}
+                              "kolmansiin"  {- ill -} "kolmansilla" {- ade -}
+                              "kolmansilta" {- abl -} "kolmansille" {- all -}
+                              "kolmansitta" {- abe -} "kolmansine"  {- com -}
+                              "kolmansin"   {- instr -}
+                              "?"           {- other -}
+            )
+          , (4, \c → infForms inf c
+                              -- singular
+                              "neljäs"      {- nom -} "neljäs"      {- acc -}
+                              "neljännen"   {- gen -} "neljättä"    {- ptv -}
+                              "neljäntenä"  {- ess -} "neljänneksi" {- transl -}
+                              "neljännessä" {- ine -} "neljännestä" {- ela -}
+                              "neljänteen"  {- ill -} "neljännellä" {- ade -}
+                              "neljänneltä" {- abl -} "neljännelle" {- all -}
+                              "neljännettä" {- abe -}
+                              (case inf of
+                                 _ | G.isComitative  inf → "neljänsine"
+                                   | G.isInstructive inf → "neljänsin"
+                                   | otherwise → "?"
+                              )
+                              -- plural
+                              "neljännet"   {- nom -} "neljännet"   {- acc -}
+                              "neljänsien"  {- gen -} "neljänsiä"   {- ptv -}
+                              "neljänsinä"  {- ess -} "neljänsiksi" {- transl -}
+                              "neljänsissä" {- ine -} "neljänsistä" {- ela -}
+                              "neljänsiin"  {- ill -} "neljänsillä" {- ade -}
+                              "neljänsiltä" {- abl -} "neljänsille" {- all -}
+                              "neljänsittä" {- abe -} "neljänsine"  {- com -}
+                              "neljänsin"   {- instr -}
+                              "?"           {- other -}
+            )
+          , (5, \c → infForms inf c
+                              -- singular
+                              "viides"      {- nom -} "viides"      {- acc -}
+                              "viidennen"   {- gen -} "viidettä"    {- ptv -}
+                              "viidentenä"  {- ess -} "viidenneksi" {- transl -}
+                              "viidennessä" {- ine -} "viidennestä" {- ela -}
+                              "viidenteen"  {- ill -} "viidennellä" {- ade -}
+                              "viidenneltä" {- abl -} "viidennelle" {- all -}
+                              "viidennettä" {- abe -}
+                              "?"           {- other -}
+                              -- plural
+                              "viidennet"   {- nom -} "viidennet"   {- acc -}
+                              "viidensien"  {- gen -} "viidensiä"   {- ptv -}
+                              "viidensinä"  {- ess -} "viidensiksi" {- transl -}
+                              "viidensissä" {- ine -} "viidensistä" {- ela -}
+                              "viidensiin"  {- ill -} "viidensillä" {- ade -}
+                              "viidensiltä" {- abl -} "viidensille" {- all -}
+                              "viidensittä" {- abe -} "viidensine"  {- com -}
+                              "viidensin"   {- instr -}
+                              "?"           {- other -}
+            )
+          , (6, \c → infForms inf c
+                              -- singular
+                              "kuudes"      {- nom -} "kuudes"      {- acc -}
+                              "kuudennen"   {- gen -} "kuudetta"    {- ptv -}
+                              "kuudentena"  {- ess -} "kuudenneksi" {- transl -}
+                              "kuudennessa" {- ine -} "kuudennesta" {- ela -}
+                              "kuudenteen"  {- ill -} "kuudennella" {- ade -}
+                              "kuudennelta" {- abl -} "kuudennelle" {- all -}
+                              "kuudennetta" {- abe -}
+                              "?"           {- other -}
+                              -- plural
+                              "kuudennet"   {- nom -} "kuudennet"   {- acc -}
+                              "kuudensien"  {- gen -} "kuudensia"   {- ptv -}
+                              "kuudensina"  {- ess -} "kuudensiksi" {- transl -}
+                              "kuudensissa" {- ine -} "kuudensista" {- ela -}
+                              "kuudensiin"  {- ill -} "kuudensilla" {- ade -}
+                              "kuudensilta" {- abl -} "kuudensille" {- all -}
+                              "kuudensitta" {- abe -} "kuudensine"  {- com -}
+                              "kuudensin"   {- instr -}
+                              "?"           {- other -}
+            )
+          , (7, \c → infForms inf c
+                              -- singular
+                              "seitsemäs"      {- nom -} "seitsemäs"      {- acc -}
+                              "seitsemännen"   {- gen -} "seitsemättä"    {- ptv -}
+                              "seitsemäntenä"  {- ess -} "seitsemänneksi" {- transl -}
+                              "seitsemännessä" {- ine -} "seitsemännestä" {- ela -}
+                              "seitsemänteen"  {- ill -} "seitsemännellä" {- ade -}
+                              "seitsemänneltä" {- abl -} "seitsemännelle" {- all -}
+                              "seitsemännettä" {- abe -}
+                              "?"              {- other -}
+                              -- plural
+                              "seitsemännet"   {- nom -} "seitsemännet"   {- acc -}
+                              "seitsemänsien"  {- gen -} "seitsemänsiä"   {- ptv -}
+                              "seitsemänsinä"  {- ess -} "seitsemänsiksi" {- transl -}
+                              "seitsemänsissä" {- ine -} "seitsemänsistä" {- ela -}
+                              "seitsemänsiin"  {- ill -} "seitsemänsillä" {- ade -}
+                              "seitsemänsiltä" {- abl -} "seitsemänsille" {- all -}
+                              "seitsemänsittä" {- abe -} "seitsemänsine"  {- com -}
+                              "seitsemänsin"   {- instr -}
+                              "?"              {- other -}
+            )
+          , (8, \c → infForms inf c
+                              -- singular
+                              "kahdeksas"      {- nom -} "kahdeksas"      {- acc -}
+                              "kahdeksannen"   {- gen -} "kahdeksatta"    {- ptv -}
+                              "kahdeksantena"  {- ess -} "kahdeksanneksi" {- transl -}
+                              "kahdeksannessa" {- ine -} "kahdeksannesta" {- ela -}
+                              "kahdeksanteen"  {- ill -} "kahdeksannella" {- ade -}
+                              "kahdeksannelta" {- abl -} "kahdeksannelle" {- all -}
+                              "kahdeksannetta" {- abe -}
+                              "?"              {- other -}
+                              -- plural
+                              "kahdeksannet"   {- nom -} "kahdeksannet"   {- acc -}
+                              "kahdeksansien"  {- gen -} "kahdeksansia"   {- ptv -}
+                              "kahdeksansina"  {- ess -} "kahdeksansiksi" {- transl -}
+                              "kahdeksansissa" {- ine -} "kahdeksansista" {- ela -}
+                              "kahdeksansiin"  {- ill -} "kahdeksansilla" {- ade -}
+                              "kahdeksansilta" {- abl -} "kahdeksansille" {- all -}
+                              "kahdeksansitta" {- abe -} "kahdeksansine"  {- com -}
+                              "kahdeksansin"   {- instr -}
+                              "?"              {- other -}
+            )
+          , (9, \c → infForms inf c
+                              -- singular
+                              "yhdeksäs"      {- nom -} "yhdeksäs"      {- acc -}
+                              "yhdeksännen"   {- gen -} "yhdeksättä"    {- ptv -}
+                              "yhdeksäntenä"  {- ess -} "yhdeksänneksi" {- transl -}
+                              "yhdeksännessä" {- ine -} "yhdeksännestä" {- ela -}
+                              "yhdeksänteen"  {- ill -} "yhdeksännellä" {- ade -}
+                              "yhdeksänneltä" {- abl -} "yhdeksännelle" {- all -}
+                              "yhdeksännettä" {- abe -}
+                              "?"             {- other -}
+                              -- plural
+                              "yhdeksännet"   {- nom -} "yhdeksännet"   {- acc -}
+                              "yhdeksänsien"  {- gen -} "yhdeksänsiä"   {- ptv -}
+                              "yhdeksänsinä"  {- ess -} "yhdeksänsiksi" {- transl -}
+                              "yhdeksänsissä" {- ine -} "yhdeksänsistä" {- ela -}
+                              "yhdeksänsiin"  {- ill -} "yhdeksänsillä" {- ade -}
+                              "yhdeksänsiltä" {- abl -} "yhdeksänsille" {- all -}
+                              "yhdeksänsittä" {- abe -} "yhdeksänsine"  {- com -}
+                              "yhdeksänsin"   {- instr -}
+                              "?"             {- other -}
+            )
+          , (10, \c → case c of
+                        CtxAdd _ (Lit _) _ → "toista" -- singular partitive ordinal 2
+                        _ → infForms inf c
+                                 -- singular
+                                 "kymmenes"      {- nom -} "kymmenes"      {- acc -}
+                                 "kymmenennen"   {- gen -} "kymmenettä"    {- ptv -}
+                                 "kymmenentenä"  {- ess -} "kymmenenneksi" {- transl -}
+                                 "kymmenennessä" {- ine -} "kymmenennestä" {- ela -}
+                                 "kymmenenteen"  {- ill -} "kymmenennellä" {- ade -}
+                                 "kymmenenneltä" {- abl -} "kymmenennelle" {- all -}
+                                 "kymmenennettä" {- abe -}
+                                 "?"             {- other -}
+                                 -- plural
+                                 "kymmenennet"   {- nom -} "kymmenennet"   {- acc -}
+                                 "kymmenensien"  {- gen -} "kymmenensiä"   {- ptv -}
+                                 "kymmenensinä"  {- ess -} "kymmenensiksi" {- transl -}
+                                 "kymmenensissä" {- ine -} "kymmenensistä" {- ela -}
+                                 "kymmenensiin"  {- ill -} "kymmenensillä" {- ade -}
+                                 "kymmenensiltä" {- abl -} "kymmenensille" {- all -}
+                                 "kymmenensittä" {- abe -} "kymmenensine"  {- com -}
+                                 "kymmenensin"   {- instr -}
+                                 "?"             {- other -}
+            )
+          , (100, \c → case c of
+                         _ → infForms inf c
+                               -- singular
+                               "sadas"      {- nom -} "sadas"      {- acc -}
+                               "sadannen"   {- gen -} "sadatta"    {- ptv -}
+                               "sadantena"  {- ess -} "sadanneksi" {- transl -}
+                               "sadannessa" {- ine -} "sadannesta" {- ela -}
+                               "sadanteen"  {- ill -} "sadannella" {- ade -}
+                               "sadannelta" {- abl -} "sadannelle" {- all -}
+                               "sadannetta" {- abe -}
+                               "?"          {- other -}
+                               -- plural
+                               "sadannet"   {- nom -} "sadannet"   {- acc -}
+                               "sadansien"  {- gen -} "sadansia"   {- ptv -}
+                               "sadansina"  {- ess -} "sadansiksi" {- transl -}
+                               "sadansissa" {- ine -} "sadansista" {- ela -}
+                               "sadansiin"  {- ill -} "sadansilla" {- ade -}
+                               "sadansilta" {- abl -} "sadansille" {- all -}
+                               "sadansitta" {- abe -} "sadansine"  {- com -}
+                               "sadansin"   {- instr -}
+                               "?"          {- other -}
+            )
+          , (1000, \c → case c of
+                         _ → infForms inf c
+                               -- singular
+                               "tuhannes"      {- nom -} "tuhannes"      {- acc -}
+                               "tuhannennen"   {- gen -} "tuhannetta"    {- ptv -}
+                               "tuhannentena"  {- ess -} "tuhannenneksi" {- transl -}
+                               "tuhannennessa" {- ine -} "tuhannennesta" {- ela -}
+                               "tuhannenteen"  {- ill -} "tuhannennella" {- ade -}
+                               "tuhannennelta" {- abl -} "tuhannennelle" {- all -}
+                               "tuhannennetta" {- abe -}
+                               "?"             {- other -}
+                               -- plural
+                               "tuhannennet"   {- nom -} "tuhannennet"   {- acc -}
+                               "tuhannensien"  {- gen -} "tuhannensia"   {- ptv -}
+                               "tuhannensina"  {- ess -} "tuhannensiksi" {- transl -}
+                               "tuhannensissa" {- ine -} "tuhannensista" {- ela -}
+                               "tuhannensiin"  {- ill -} "tuhannensilla" {- ade -}
+                               "tuhannensilta" {- abl -} "tuhannensille" {- all -}
+                               "tuhannensitta" {- abe -} "tuhannensine"  {- com -}
+                               "tuhannensin"   {- instr -}
+                               "?"             {- other -}
+            )
+          ]
+
+infForms ∷ ( G.Singular i, G.Plural i
+           , G.Abessive i
+           , G.Accusative i
+           , G.Comitative i
+           , G.Delative i
+           , G.Distributive i
+           , G.DistributiveTemporal i
+           , G.Essive i
+           , G.Genitive i
+           , G.Instructive i
+           , G.Lative i
+           , G.LocativeInessive i
+           , G.LocativeElative i
+           , G.LocativeIllative i
+           , G.LocativeAdessive i
+           , G.LocativeAblative i
+           , G.LocativeAllative i
+           , G.Multiplicative i
+           , G.Nominative i
+           , G.Partitive i
+           , G.Sublative i
+           , G.SuperEssive i
+           , G.Translative i
+           )
+         ⇒ i → Ctx (Exp i)
+         → Text → Text → Text → Text → Text → Text → Text → Text → Text → Text
+         → Text → Text → Text → Text → Text → Text → Text → Text → Text → Text
+         → Text → Text → Text → Text → Text → Text → Text → Text → Text → Text → Text
+infForms inf _
+         s_nom s_acc s_gen s_ptv s_ess s_transl
+         s_ine s_ela s_ill s_ade s_abl s_all s_abe
+         s_other
+         p_nom p_acc p_gen p_ptv p_ess p_transl
+         p_ine p_ela p_ill p_ade p_abl p_all p_abe p_com p_instr
+         p_other
+    | G.isSingular inf = singularForms
+    | G.isPlural   inf = pluralForms
+    | otherwise        = "?"
+  where
+    singularForms
+        | G.isNominative       inf = s_nom
+        | G.isAccusative       inf = s_acc
+        | G.isGenitive         inf = s_gen
+        | G.isPartitive        inf = s_ptv
+        | G.isEssive           inf = s_ess
+        | G.isTranslative      inf = s_transl
+        | G.isLocativeInessive inf = s_ine
+        | G.isLocativeElative  inf = s_ela
+        | G.isLocativeIllative inf = s_ill
+        | G.isLocativeAdessive inf = s_ade
+        | G.isLocativeAblative inf = s_abl
+        | G.isLocativeAllative inf = s_all
+        | G.isAbessive         inf = s_abe
+        | otherwise                = s_other
+    pluralForms
+        | G.isNominative       inf = p_nom
+        | G.isAccusative       inf = p_acc
+        | G.isGenitive         inf = p_gen
+        | G.isPartitive        inf = p_ptv
+        | G.isEssive           inf = p_ess
+        | G.isTranslative      inf = p_transl
+        | G.isLocativeInessive inf = p_ine
+        | G.isLocativeElative  inf = p_ela
+        | G.isLocativeIllative inf = p_ill
+        | G.isLocativeAdessive inf = p_ade
+        | G.isLocativeAblative inf = p_abl
+        | G.isLocativeAllative inf = p_all
+        | G.isAbessive         inf = p_abe
+        | G.isComitative       inf = p_com
+        | G.isInstructive      inf = p_instr
+        | otherwise                = p_other
diff --git a/src/Text/Numeral/Language/FR.hs b/src/Text/Numeral/Language/FR.hs
--- a/src/Text/Numeral/Language/FR.hs
+++ b/src/Text/Numeral/Language/FR.hs
@@ -1,8 +1,8 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
 
 {-|
 [@ISO639-1@]        fr
@@ -17,8 +17,16 @@
 -}
 
 module Text.Numeral.Language.FR
-    ( cardinal
-    , struct
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+    , ordinal
+      -- * Structure
+    , cardinalStruct
+    , ordinalStruct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -29,60 +37,84 @@
 import "base" Data.Bool     ( otherwise )
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
 import "base" Data.Ord      ( (<) )
-import "base" Data.String   ( IsString )
-import "base" Prelude       ( Integral, (-), Integer )
+import "base" Prelude       ( Integral, (-), negate )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import "base-unicode-symbols" Data.Ord.Unicode ( (≤), (≥) )
+import "base-unicode-symbols" Prelude.Unicode ( ℤ )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.BigNum      as BN
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum  as BN
+import qualified "this" Text.Numeral.Exp     as E
+import qualified "this" Text.Numeral.Grammar as G
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- FR
 --------------------------------------------------------------------------------
 
-{-
-Sources:
-  http://www.sf.airnet.ne.jp/~ts/language/number/french.html
-  http://www.french-linguistics.co.uk/tutorials/numbers/
--}
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "fr"
+    , entIso639_2    = ["fre"]
+    , entIso639_3    = Just "fra"
+    , entNativeNames = ["Français"]
+    , entEnglishName = Just "French"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = cardinalStruct
+                       }
+    , entOrdinal     = Just Conversion
+                       { toNumeral   = ordinal
+                       , toStructure = ordinalStruct
+                       }
+    }
 
-cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (G.Feminine i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ cardinalStruct
 
-struct ∷ ( Integral α, C.Scale α
-         , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β
-         )
-       ⇒ α → β
-struct = pos $ fix $ rule `combine` pelletierScale1 R L BN.rule
-    where
-      rule = findRule (   0, lit         )
-                    [ (  11, add   10 L  )
-                    , (  17, add   10 R  )
-                    , (  20, lit         )
-                    , (  21, add   20 R  )
-                    , (  30, mul   10 R L)
-                    , (  70, add   60 R  )
-                    , (  80, mul   20 R L)
-                    , (  89, add   80 R  )
-                    , ( 100, step  100   10 R L)
-                    , (1000, step 1000 1000 R L)
-                    ]
-                      (dec 6 - 1)
+ordinal ∷ (G.Feminine i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+ordinal inf = ordinalRepr inf ∘ ordinalStruct
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
-cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
-               , reprScale = pelletierRepr
-               , reprAdd   = Just (⊞)
-               , reprMul   = Just (⊡)
-               , reprNeg   = Just $ \_ _ → "moins "
-               }
+cardinalStruct ∷ ( Integral α, E.Scale α
+                 , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
+                 )
+               ⇒ α → β
+cardinalStruct = pos $ fix $ rule `combine` pelletierScale1 R L BN.rule
+
+ordinalStruct ∷ ( Integral α, E.Scale α
+                , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
+                )
+              ⇒ α → β
+ordinalStruct = pos $ fix $ rule `combine` pelletierScale R L BN.rule
+
+rule ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ Rule α β
+rule = findRule (   0, lit         )
+              [ (  11, add   10 L  )
+              , (  17, add   10 R  )
+              , (  20, lit         )
+              , (  21, add   20 R  )
+              , (  30, mul   10 R L)
+              , (  70, add   60 R  )
+              , (  80, mul   20 R L)
+              , (  89, add   80 R  )
+              , ( 100, step  100   10 R L)
+              , (1000, step 1000 1000 R L)
+              ]
+                (dec 6 - 1)
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 60000 - 1 in (negate x, x)
+
+genericRepr ∷ Repr i
+genericRepr = defaultRepr
+              { reprAdd   = Just (⊞)
+              , reprMul   = Just (⊡)
+              , reprNeg   = Just $ \_ _ → "moins "
+              }
     where
       (Lit n                ⊞ Lit 10) _       | n ≤ 6 = ""
       (Lit 10               ⊞ Lit n ) _       | n ≥ 7 = "-"
@@ -97,10 +129,22 @@
       (_ ⊡ Lit 20) _ = "-"
       (_ ⊡ _     ) _ = " "
 
-      syms =
+cardinalRepr ∷ (G.Feminine i) ⇒ i → Exp i → Maybe Text
+cardinalRepr = render genericRepr
+               { reprValue = \inf n → M.lookup n (syms inf)
+               , reprScale = BN.pelletierRepr (BN.quantityName "illion"  "illions")
+                                              (BN.quantityName "illiard" "illiards")
+                                              bigNumSyms
+               }
+    where
+      syms inf =
           M.fromList
           [ (0, const "zéro")
-          , (1, ten   "un"     "on"     "un")
+          , (1, \c → case c of
+                       CtxAdd _ (Lit 10) _  → "on"
+                       _ | G.isFeminine inf → "une"
+                         | otherwise        → "un"
+            )
           , (2, ten   "deux"   "dou"    "deux")
           , (3, ten   "trois"  "trei"   "tren")
           , (4, ten   "quatre" "quator" "quar")
@@ -132,17 +176,84 @@
                         CtxMul _ (Lit 10) _ → m
                         _                   → n
 
-pelletierRepr ∷ (IsString s, Monoid s)
-              ⇒ Integer → Integer → Exp → Ctx Exp → Maybe s
-pelletierRepr = BN.pelletierRepr
-                  "illion" "illions"
-                  "illiard" "illiards"
-                  [ (1, BN.forms "m"  "uno" "uno"  ""    "")
-                  , (3, BN.forms "tr" "tré" "tres" "tri" "tre")
-                  , (10, \c → case c of
-                                CtxAdd _ (Lit 100) _              → "deci"
-                                CtxMul _ _ (CtxAdd _ (Lit 100) _) → "ginta"
-                                CtxMul {}                         → "gint"
-                                _                                 → "déc"
-                    )
-                  ]
+ordinalRepr ∷ (G.Feminine i) ⇒ i → Exp i → Maybe Text
+ordinalRepr = render genericRepr
+              { reprValue = \inf n → M.lookup n (syms inf)
+              , reprScale = BN.pelletierRepr ( BN.ordQuantityName "illion"  "illionième"
+                                                                  "illions" "illionième"
+                                             )
+                                             ( BN.ordQuantityName "illiard"  "illiardième"
+                                                                  "illiards" "illiardième"
+                                             )
+                                             bigNumSyms
+              }
+    where
+      syms inf =
+          M.fromList
+          [ (0, \c → case c of
+                       CtxEmpty → "zéroth"
+                       _        → "zéro"
+            )
+          , (1, \c → case c of
+                       CtxEmpty
+                         | G.isFeminine inf → "première"
+                         | otherwise        → "premier"
+                       CtxAdd _ (Lit 10) _  → "on"
+                       _ | isOutside R c    → if G.isFeminine inf
+                                              then "uneième"
+                                              else "unième"
+                         | G.isFeminine inf → "une"
+                         | otherwise        → "un"
+            )
+          , (2, ten   "deuxième"  "deux"   "dou"    "deux")
+          , (3, ten   "troisième" "trois"  "trei"   "tren")
+          , (4, ten   "quatrième" "quatre" "quator" "quar")
+          , (5, ten   "cinquième" "cinq"   "quin"   "cinqu")
+          , (6, ten   "sixième"   "six"    "sei"    "soix")
+          , (7, \c → if isOutside R c then "septième" else "sept")
+          , (8, \c → if isOutside R c then "huitième" else "huit")
+          , (9, \c → if isOutside R c then "neuvième" else "neuf")
+          , (10, \c → case c of
+                        CtxAdd R (Lit _) _ | isOutside R c → "zième"
+                                           | otherwise     → "ze"
+                        CtxAdd L (Lit _) _                 → "dix"
+                        CtxMul _ (Lit 3) _ | isOutside R c → "tième"
+                                           | otherwise     → "te"
+                        CtxMul R _       _ | isOutside R c → "antième"
+                                           | otherwise     → "ante"
+                        _                  | isOutside R c → "dixième"
+                                           | otherwise     → "dix"
+            )
+          , (20, \c → case c of
+                        _ | isOutside R c → "vingtième"
+                        CtxMul _ _ CtxEmpty → "vingts"
+                        _                   → "vingt"
+            )
+          , (100, \c → case c of
+                         _ | isOutside R c   → "centième"
+                         CtxMul R _ CtxEmpty → "cents"
+                         _                   → "cent"
+            )
+          , (1000, \c → if isOutside R c then "millième" else "mille")
+          ]
+
+      ten o n a m ctx =
+          case ctx of
+            CtxAdd _ (Lit 10) _ | isOutside R ctx → o
+                                | otherwise       → a
+            CtxMul _ (Lit 10) _ | isOutside R ctx → o
+                                | otherwise       → m
+            _                   | isOutside R ctx → o
+                                | otherwise       → n
+
+bigNumSyms ∷ [(ℤ, Ctx (Exp i) → Text)]
+bigNumSyms =
+    [ (1, BN.forms "m"  "uno" "uno"  ""    "")
+    , (3, BN.forms "tr" "tré" "tres" "tri" "tre")
+    , (10, \c → case c of
+                  CtxAdd _ (Lit 100) _              → "deci"
+                  CtxMul _ _ (CtxAdd _ (Lit 100) _) → "ginta"
+                  CtxMul {}                         → "gint"
+                  _                                 → "déc"
+      )
+    ]
diff --git a/src/Text/Numeral/Language/FUR.hs b/src/Text/Numeral/Language/FUR.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/FUR.hs
@@ -0,0 +1,145 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        fur
+
+[@ISO639-3@]        fur
+
+[@Native name@]     Furlan
+
+[@English name@]    Friulan
+-}
+
+module Text.Numeral.Language.FUR
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Data.Bool     ( otherwise )
+import "base" Data.Function ( ($), const, fix )
+import "base" Data.Maybe    ( Maybe(Just) )
+import "base" Prelude       ( Integral, (-), negate )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Data.Ord.Unicode      ( (≤) )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum  as BN
+import qualified "this" Text.Numeral.Exp     as E
+import qualified "this" Text.Numeral.Grammar as G
+import           "this" Text.Numeral.Misc ( dec )
+import           "this" Text.Numeral.Entry
+import qualified "this" Text.Numeral.Language.IT as IT ( rule )
+import           "this" Text.Numeral.Render.Utils ( addCtx, mulCtx )
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- FUR
+--------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_2    = ["fur"]
+    , entIso639_3    = Just "fur"
+    , entNativeNames = ["Furlan", "marilenghe"]
+    , entEnglishName = Just "Friulan"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
+
+cardinal ∷ (G.Masculine i, G.Feminine i, Integral α, E.Scale α)
+         ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Add β, E.Mul β, E.Scale β
+         )
+       ⇒ α → β
+struct = fix $ IT.rule `combine` pelletierScale1 R L BN.rule
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 12 - 1 in (negate x, x)
+
+cardinalRepr ∷ (G.Feminine i, G.Masculine i) ⇒ i → Exp i → Maybe Text
+cardinalRepr = render defaultRepr
+               { reprValue = \inf n → M.lookup n (syms inf)
+               , reprAdd   = Just (⊞)
+               , reprMul   = Just (⊡)
+               , reprScale = BN.pelletierRepr
+                               (BN.quantityName "ilion"  "ilions")
+                               (BN.quantityName "iliart" "iliarts")
+                               []
+               }
+    where
+      (         Lit   20  ⊞ _                        ) _ = "e"
+      (         Lit  100  ⊞ _                        ) _ = " e "
+      (         Lit 1000  ⊞ (        Lit 100 `Add` _)) _ = " "
+      (         Lit 1000  ⊞ (_ `Mul` Lit 100 `Add` _)) _ = " "
+      (         Lit 1000  ⊞ _                        ) _ = " e "
+      ((_ `Mul` Lit  100) ⊞ _                        ) _ = " e "
+      ((_ `Mul` Lit 1000) ⊞ (        Lit 100 `Add` _)) _ = " "
+      ((_ `Mul` Lit 1000) ⊞ (_ `Mul` Lit 100 `Add` _)) _ = " "
+      ((_ `Mul` Lit 1000) ⊞ _                        ) _ = " e "
+      (_                  ⊞ _                        ) _ = ""
+
+      (_ ⊡ Lit 1000) _ = " "
+      (_ ⊡ Scale {}) _ = " "
+      (_ ⊡ _       ) _ = ""
+
+      syms inf =
+          M.fromList
+          [ (0, const "zero")
+          , (1, \c → case c of
+                       _ | G.isFeminine  inf → "une"
+                         | otherwise         → "un"
+            )
+          , (2, addCtx 10 "do" $ mulCtx 100 "dus"
+                $ \c → case c of
+                         _ | G.isFeminine inf → "dôs"
+                           | otherwise        → "doi"
+            )
+          , (3, addCtx 10  "tre"  $ mulCtx 10 "tr"
+              $ mulCtx 100 "tres" $ const     "trê"
+            )
+          , (4, addCtx 10 "cutuar" $ mulCtx 10 "cuar"  $ const "cuatri")
+          , (5, addCtx 10 "cuin"   $ mulCtx 10 "cincu" $ const "cinc")
+          , (6, addCtx 10 "se"     $ mulCtx 10 "sess"  $ const "sîs")
+          , (7,                      mulCtx 10 "set"   $ const "siet")
+          , (8,                      mulCtx 10 "ot"    $ const "vot")
+          , (9,                      mulCtx 10 "nov"   $ const "nûf")
+          , (10, \c → case c of
+                        CtxAdd R (Lit n) _
+                            | n ≤ 7        → "dis"
+                        CtxAdd L _       _ → "dise"
+                        CtxMul _ (Lit 3) _ → "ente"
+                        CtxMul _ (Lit n) _
+                            | n ≤ 9        → "ante"
+                        _                  → "dîs"
+            )
+          , (20, const "vincj")
+          , (100, \c → case c of
+                         CtxMul _ (Lit n) _
+                             | n ≤ 3     → "inte"
+                             | otherwise → "cent"
+                         _               → "cent"
+            )
+          , (1000, const "mil")
+          ]
diff --git a/src/Text/Numeral/Language/GSW.hs b/src/Text/Numeral/Language/GSW.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/GSW.hs
@@ -0,0 +1,126 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        gse
+
+[@ISO639-3@]        gse
+
+[@Native name@]     Schwyzerdütsch
+
+[@English name@]    Swiss German
+-}
+
+module Text.Numeral.Language.GSW
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    ) where
+
+
+-------------------------------------------------------------------------------
+-- Imports
+-------------------------------------------------------------------------------
+
+import "base" Data.Function ( ($), const )
+import "base" Data.Maybe    ( Maybe(Just) )
+import "base" Prelude       ( Integral, (-), negate )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Language.DE ( struct )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- GSW
+--------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_2    = ["gse"]
+    , entIso639_3    = Just "gse"
+    , entNativeNames = ["Schwyzerdütsch"]
+    , entEnglishName = Just "Swiss German"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
+
+cardinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 6 - 1 in (negate x, x)
+
+genericRepr ∷ Repr i
+genericRepr = defaultRepr
+              { reprAdd   = Just (⊞)
+              , reprMul   = Just $ \_ _ _ → ""
+              }
+    where
+      (_       ⊞ (_ `Mul` Lit 10)) _ = "e"
+      (Lit 100 ⊞ Lit 1)            _ = "und"
+      (_       ⊞ _ )               _ = ""
+
+cardinalRepr ∷ i → Exp i → Maybe Text
+cardinalRepr = render genericRepr
+               { reprValue = \_ n → M.lookup n syms }
+    where
+      syms =
+          M.fromList
+          [ (1, \c → case c of
+                       CtxAdd _ (Lit 100) _ → "äis"
+                       CtxAdd {}            → "ein"
+                       _                    → "eis"
+            )
+          , (2, \c → case c of
+                       CtxMul _ (Lit 10) _ → "zwän"
+                       _                   → "zwöi"
+            )
+          , (3, \c → case c of
+                       CtxAdd _ (Lit 10) _ → "dry"
+                       CtxMul _ (Lit 10) _ → "drys"
+                       _                   → "drü"
+            )
+          , (4, const "vier")
+          , (5, const "füf")
+          , (6, \c → case c of
+                       CtxMul _ (Lit 10) _ → "sëch"
+                       _                   → "sächs"
+            )
+          , (7, \c → case c of
+                       CtxAdd _ (_ `Mul` Lit 10) _ → "siben"
+                       _                           → "sibe"
+            )
+          , (8, \c → case c of
+                       CtxMul _ (Lit 10) _ → "ach"
+                       _                   → "acht"
+            )
+          , (9, \c → case c of
+                       CtxAdd _ (_ `Mul` Lit 10) _ → "nün"
+                       _                           → "nüün"
+            )
+          , (10, \c → case c of
+                        CtxMul _ (Lit 3) _ → "sg"
+                        CtxMul {}          → "zg"
+                        _                  → "zäh"
+            )
+          , (11, const "euf")
+          , (12, const "zwüof")
+          , (100, const "hundert")
+          ]
diff --git a/src/Text/Numeral/Language/GV.hs b/src/Text/Numeral/Language/GV.hs
--- a/src/Text/Numeral/Language/GV.hs
+++ b/src/Text/Numeral/Language/GV.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        gv
@@ -17,8 +16,14 @@
 -}
 
 module Text.Numeral.Language.GV
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -28,30 +33,37 @@
 
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
 import "base" Prelude       ( Integral )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 -------------------------------------------------------------------------------
 -- GV
 -------------------------------------------------------------------------------
 
-{-
-Sources:
-  http://www.sf.airnet.ne.jp/~ts/language/number/manx.html
-  http://www.gaelg.iofm.net/LESSONS/P/P19.html
-  http://www.gaelg.iofm.net/LESSONS/mona/Lessons.pdf
--}
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "gv"
+    , entIso639_2    = ["glv"]
+    , entIso639_3    = Just "glv"
+    , entNativeNames = ["Gaelg"]
+    , entEnglishName = Just "Manx"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ α → β
 struct = checkPos
        $ fix
        $ findRule (   1, lit       )
@@ -66,9 +78,12 @@
                 ]
                    1000
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (1, 1000)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprAdd   = Just (⊞)
                , reprMul   = Just $ \_ _ _ → " "
                }
diff --git a/src/Text/Numeral/Language/HE.hs b/src/Text/Numeral/Language/HE.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/HE.hs
@@ -0,0 +1,172 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        he
+
+[@ISO639-2@]        heb
+
+[@ISO639-3@]        heb
+
+[@Native name@]     עִבְרִית
+
+[@English name@]    Modern Hebrew
+-}
+
+module Text.Numeral.Language.HE
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Data.Function ( ($), fix )
+import "base" Data.List     ( concat )
+import "base" Data.Maybe    ( Maybe(Just) )
+import "base" Prelude       ( Integral, (+), div, negate )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Data.Monoid.Unicode   ( (⊕) )
+import "base-unicode-symbols" Data.Ord.Unicode      ( (≤) )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- HE
+--------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1       = Just "he"
+    , entIso639_2       = ["heb"]
+    , entIso639_3       = Just "heb"
+    , entNativeNames    = ["עִבְרִית"]
+    , entEnglishName    = Just "Modern Hebrew"
+    , entCardinal       = Just Conversion
+                          { toNumeral   = cardinal
+                          , toStructure = struct
+                          }
+    }
+
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ ( Integral α
+         , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Dual β, E.Plural β
+         )
+       ⇒ α → β
+struct = pos
+       $ fix
+       $ findRule (  0, lit)
+                  ( [ (11, add 10 L)
+                    , (20, dual ∘ mapRule (`div` 10) lit)
+                    , (21, add 20 R)
+                    ]
+                  ⊕ concat [ [ (n, plural ∘ mapRule (`div` 10) lit)
+                             , (n+1, add n R)
+                             ]
+                           | n ← [20,30..90]
+                           ]
+                  ⊕ [ (100, step 100 10 R L)
+                    , (200, dual ∘ mapRule (`div` 2) lit)
+                    , (201, add 200 R)
+                    , (300, step 100 10 R L)
+                    ]
+                  )
+                  1000
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = 1000 in (negate x, x)
+
+-- TODO: Handle inflection, mainly masculine and feminine
+-- gender. Maybe get rid of Dual and Plural in the expression language
+-- and use grammatical number for that.
+cardinalRepr ∷ i → Exp i → Maybe Text
+cardinalRepr = render defaultRepr
+               { reprValue = \_ n → M.lookup n syms
+               , reprAdd   = Just (⊞)
+               , reprMul   = Just (⊡)
+               , reprNeg   = Just $ \_ _ → "מינוס "
+               , reprAddCombine = Just addCombine
+               }
+    where
+      (_        ⊞ Lit 10) _ = "ה"
+      (Dual   _ ⊞ _     ) _ = " ו"
+      (Plural _ ⊞ _     ) _ = " ו"
+      (_        ⊞ _     ) _ = " "
+
+      (_ ⊡ Lit 10) _ = ""
+      (_ ⊡ _     ) _ = " "
+
+      addCombine a x _ y (Lit 10) = x ⊕ " " ⊕ y ⊕ a
+      addCombine a x _ y _        = x ⊕ a ⊕ y
+
+      syms =
+          M.fromList
+          [ (0, \c → case c of
+                       _ → "אפס"
+            )
+          , (1, \c → case c of
+                       _ → "אחת"
+            )
+          , (2, \c → case c of
+                       CtxAdd _ (Lit 10) _ → "שתים"
+                       CtxDual {}          → "עשרים"
+                       _                   → "שתיים"
+            )
+          , (3, \c → case c of
+                       CtxPlural {} → "שלושים"
+                       _            → "שלוש"
+            )
+          , (4, \c → case c of
+                       CtxPlural {} → "ארבעים"
+                       _            → "ארבע"
+            )
+          , (5, \c → case c of
+                       CtxPlural {} → "חמישים"
+                       _            → "חמש"
+            )
+          , (6, \c → case c of
+                       CtxPlural {} → "ששים"
+                       _            → "שש"
+            )
+          , (7, \c → case c of
+                       CtxPlural {} → "שבעים"
+                       _            → "שבע"
+            )
+          , (8, \c → case c of
+                       CtxPlural {} → "שמונים"
+                       _            → "שמונה"
+            )
+          , (9, \c → case c of
+                       CtxPlural {} → "תשעים"
+                       _            → "תשע"
+            )
+          , (10, \c → case c of
+                        CtxMul _ (Lit n) _ | n ≤ 9 → ""
+                        _ → "עשר"
+            )
+          , (100, \c → case c of
+                         CtxDual   {} → "מאתיים"
+                         CtxMul    {} → "מאות"
+                         _            → "מאה"
+            )
+          , (1000, \c → case c of
+                          _ → "אלף"
+            )
+          ]
diff --git a/src/Text/Numeral/Language/HOP.hs b/src/Text/Numeral/Language/HOP.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/HOP.hs
@@ -0,0 +1,128 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        hop
+
+[@Native name@]     Hopilàvayi
+
+[@English name@]    Hopi
+-}
+
+module Text.Numeral.Language.HOP
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Data.Function ( ($), const, fix )
+import "base" Data.Maybe    ( Maybe(Just) )
+import "base" Prelude       ( Integral, (-), negate )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Data.List.Unicode     ( (∈) )
+import "base-unicode-symbols" Data.Monoid.Unicode   ( (⊕) )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp     as E
+import "this" Text.Numeral.Entry
+import "this" Text.Numeral.Render.Utils ( mulCtx )
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- HOP
+--------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_3    = Just "hop"
+    , entNativeNames = ["Hopilàvayi"]
+    , entEnglishName = Just "Hopi"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
+
+cardinal ∷ (Integral α, E.Scale α)⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ ( Integral α
+         , E.Unknown β, E.Lit β, E.Add β, E.Mul β
+         )
+       ⇒ α → β
+struct = fix
+       $ findRule ( 0, lit)
+                [ (11, add 10 R)
+                , (20, lit)
+                , (21, add 20 R)
+                , (30, mul 10 R L)
+                ]
+                  (100)
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (1, 100)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
+cardinalRepr = render defaultRepr
+               { reprValue = \inf n → M.lookup n (syms inf)
+               , reprAdd   = Just (⊞)
+               , reprAddCombine = Just addCombine
+               , reprMul   = Just $ \_ _ _ → " "
+               }
+    where
+      (Lit n          ⊞ _) _ | n ∈ [10, 20] = " niikyang "
+      (Mul _ (Lit 10) ⊞ _) _                = " niikyang "
+      (_              ⊞ _) _                = " "
+
+      addCombine a x (Lit n) y _ | n ∈ [10, 20] = x ⊕ a ⊕ y ⊕ " siikya’ta"
+      addCombine a x (Mul _ (Lit 10)) y _       = x ⊕ a ⊕ y ⊕ " siikya’ta"
+      addCombine a x _                y _       = x ⊕ a ⊕ y
+
+      syms _ =
+          M.fromList
+          [ (1, \c → case c of
+                       CtxAdd {} → "suk"
+                       _         → "suukya’"
+            )
+          , (2, \c → case c of
+                       CtxAdd {} → "löqmuy"
+                       _         → "lööyöm"
+            )
+          , (3, \c → case c of
+                       CtxAdd {} → "paykomuy"
+                       CtxMul {} → "payiv"
+                       _         → "pàayom"
+            )
+          , (4, \c → case c of
+                       CtxAdd {} → "naalöqmuy"
+                       CtxMul {} → "naalöv"
+                       _         → "naalöyöm"
+            )
+          , (5, mulCtx 10 "tsivotsikiv"  $ const "tsivot")
+          , (6, mulCtx 10 "navaysikiv"   $ const "navay")
+          , (7, mulCtx 10 "tsange’sikiv" $ const "tsange’")
+          , (8, mulCtx 10 "nanalsikiv"   $ const "nanalt")
+          , (9, mulCtx 10 "peve’sikiv"   $ const "pevt")
+          , (10, \c → case c of
+                       CtxMul L _ _ → "palotsikiv"
+                       _            → "pakwt"
+            )
+          , (20, const "sunat")
+          ]
diff --git a/src/Text/Numeral/Language/IT.hs b/src/Text/Numeral/Language/IT.hs
--- a/src/Text/Numeral/Language/IT.hs
+++ b/src/Text/Numeral/Language/IT.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        it
@@ -17,8 +16,16 @@
 -}
 
 module Text.Numeral.Language.IT
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+    , ordinal
+      -- * Structure
     , struct
+    , rule
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -26,59 +33,84 @@
 -- Imports
 --------------------------------------------------------------------------------
 
+import "base" Data.Bool     ( otherwise )
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
-import "base" Prelude       ( Integral, (-), Integer )
+import "base" Data.Ord      ( Ord )
+import "base" Prelude       ( Integral, (-), negate )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import "base-unicode-symbols" Data.List.Unicode     ( (∈) )
 import "base-unicode-symbols" Data.Ord.Unicode      ( (≥) )
+import "base-unicode-symbols" Prelude.Unicode       ( ℤ )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.BigNum      as BN
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum  as BN
+import qualified "this" Text.Numeral.Exp     as E
+import qualified "this" Text.Numeral.Grammar as G
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- IT
 --------------------------------------------------------------------------------
 
--- Sources:
---   http://www.sf.airnet.ne.jp/~ts/language/number/italian.html
---   http://www.orbilat.com/Languages/Italian/Grammar/Italian-Numerals.html
---   http://italian.about.com/library/weekly/aa042600a.htm
---   http://www.suite101.com/content/how-to-count-in-italian-a146487
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1       = Just "it"
+    , entIso639_2       = ["ita"]
+    , entIso639_3       = Just "ita"
+    , entNativeNames    = ["Italiano"]
+    , entEnglishName    = Just "Italian"
+    , entCardinal       = Just Conversion
+                          { toNumeral   = cardinal
+                          , toStructure = struct
+                          }
+    , entOrdinal        = Just Conversion
+                          { toNumeral   = ordinal
+                          , toStructure = struct
+                          }
+    }
 
-cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (G.Masculine i, G.Feminine i, Integral α, E.Scale α)
+         ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
 
-struct ∷ ( Integral α, C.Scale α
-         , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β
+ordinal ∷ (G.Masculine i, G.Feminine i, Integral α, E.Scale α)
+        ⇒ i → α → Maybe Text
+ordinal inf = ordinalRepr inf ∘ struct
+
+rule ∷ ( Integral α, Ord α
+       , E.Unknown β, E.Lit β, E.Add β, E.Mul β
+       )
+     ⇒ Rule α β
+rule = findRule (   0, lit         )
+              [ (  11, add   10 L  )
+              , (  17, add   10 R  )
+              , (  20, lit         )
+              , (  21, add   20 R  )
+              , (  30, mul   10 R L)
+              , ( 100, step  100   10 R L)
+              , (1000, step 1000 1000 R L)
+              ]
+                (dec 6 - 1)
+
+struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
          )
        ⇒ α → β
 struct = pos $ fix $ rule `combine` pelletierScale R L BN.rule
-    where
-      rule = findRule (   0, lit         )
-                    [ (  11, add   10 L  )
-                    , (  17, add   10 R  )
-                    , (  20, lit         )
-                    , (  21, add   20 R  )
-                    , (  30, mul   10 R L)
-                    , ( 100, step  100   10 R L)
-                    , (1000, step 1000 1000 R L)
-                    ]
-                      (dec 6 - 1)
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
-cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
-               , reprScale = pelletierRepr
-               , reprAdd   = Just (⊞)
-               , reprMul   = Just (⊡)
-               , reprNeg   = Just $ \_ _ → "meno "
-               }
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 60000 - 1 in (negate x, x)
+
+genericRepr ∷ Repr i
+genericRepr = defaultRepr
+              { reprAdd   = Just (⊞)
+              , reprMul   = Just (⊡)
+              , reprNeg   = Just $ \_ _ → "meno "
+              }
     where
       (Lit 10                ⊞ Lit 7) _ = "as"
       (Lit 10                ⊞ Lit 9) _ = "an"
@@ -90,53 +122,39 @@
       (_     ⊡ Scale _ _ _) _ = " "
       (_     ⊡ _          ) _ = ""
 
-      syms =
+cardinalRepr ∷ (G.Feminine i, G.Masculine i) ⇒ i → Exp i → Maybe Text
+cardinalRepr = render genericRepr
+               { reprValue = \inf n → M.lookup n (syms inf)
+               , reprScale = BN.pelletierRepr
+                               (BN.quantityName "ilione"  "ilioni")
+                               (BN.quantityName "iliardo" "iliardi")
+                               bigNumSyms
+               }
+    where
+      syms inf =
           M.fromList
           [ (0, const "zero")
           , (1, \c → case c of
-                       CtxAdd _ (Lit 10) _ → "un"
-                       _                   → "uno"
-            )
-          , (2, \c → case c of
-                       CtxAdd _ (Lit 10) _ → "do"
-                       _                   → "due"
+                       CtxAdd _ (Lit 10) _   → "un"
+                       _ | G.isFeminine  inf → "una"
+                         | G.isMasculine inf → "un"
+                         | otherwise         → "uno"
             )
+          , (2, forms "due" "do" "du")
           , (3, \c → case c of
                        CtxAdd R _        _ → "tré"
                        CtxMul _ (Lit 10) _ → "tren"
                        _                   → "tre"
             )
-          , (4, \c → case c of
-                       CtxAdd _ (Lit 10) _ → "quattor"
-                       CtxMul _ (Lit 10) _ → "quar"
-                       _                   → "quattro"
-            )
-          , (5, \c → case c of
-                       CtxAdd _ (Lit 10) _ → "quin"
-                       CtxMul _ (Lit 10) _ → "cinqu"
-                       _                   → "cinque"
-            )
-          , (6, \c → case c of
-                       CtxAdd _ (Lit 10) _ → "se"
-                       CtxMul _ (Lit 10) _ → "sess"
-                       _                   → "sei"
-            )
-          , (7, \c → case c of
-                       CtxMul _ (Lit 10) _ → "sett"
-                       _                   → "sette"
-            )
-          , (8, \c → case c of
-                       CtxMul _ (Lit 10) _ → "ott"
-                       _                   → "otto"
-            )
-          , (9, \c → case c of
-                       CtxMul _ (Lit 10) _ → "nov"
-                       _                   → "nove"
-            )
+          , (4, forms "quattro" "quattor" "quar")
+          , (5, forms "cinque"  "quin"    "cinqu")
+          , (6, forms "sei"     "se"      "sess")
+          , (7, forms "sette"   "sette"   "sett")
+          , (8, forms "otto"    "otto"    "ott")
+          , (9, forms "nove"    "nove"    "nov")
           , (10, \c → case c of
                         CtxAdd _ (Lit _) _ → "dici"
-                        -- Last vowel removed because of a
-                        -- phonetic rule:
+                        -- Last vowel removed because of a phonetic rule:
                         CtxMul _ (Lit _) (CtxAdd _ (Lit n) _)
                             | n ∈ [1,8]    → "t"
                         CtxMul R (Lit _) _ → "ta"
@@ -162,12 +180,93 @@
             )
           ]
 
-pelletierRepr ∷ (IsString s, Monoid s)
-              ⇒ Integer → Integer → Exp → Ctx Exp → Maybe s
-pelletierRepr = BN.pelletierRepr
-                  "ilione"  "ilioni"
-                  "iliardo" "iliardi"
-                  [ (6, BN.forms "sest" "sex"    "ses"    "sexa"   "ses")
-                  , (7, BN.forms "sett" "septen" "septem" "septua" "septin")
-                  , (8, BN.forms "ott"  "otto"   "otto"   "otto"   "ottin")
-                  ]
+      forms ∷ s → s → s → Ctx (Exp i) → s
+      forms n a m c = case c of
+                        CtxAdd _ (Lit 10) _ → a
+                        CtxMul _ (Lit 10) _ → m
+                        _                   → n
+
+ordinalRepr ∷ (G.Feminine i) ⇒ i → Exp i → Maybe Text
+ordinalRepr = render genericRepr
+              { reprValue = \inf n → M.lookup n (syms inf)
+              , reprScale = BN.pelletierRepr
+                              ( BN.ordQuantityName "ilione" "ilionesimo"
+                                                   "ilioni" "ilionesimo"
+                              )
+                              ( BN.ordQuantityName "iliardo" "iliardesimo"
+                                                   "iliardi" "iliardesimo"
+                              )
+                              bigNumSyms
+              }
+    where
+      syms inf =
+          M.fromList
+          [ (0, const "zero")
+          , (1, forms "prima" "primo" "unesimo" "uno" "un" "un")
+          , (2, forms "seconda" "secondo" "duesimo" "due" "do" "due")
+          , (3, \c → case c of
+                       CtxEmpty
+                         | G.isFeminine inf → "terza"
+                         | otherwise        → "terzo"
+                       _ | isOutside R c    → "treesimo"
+                       CtxAdd R _        _  → "tré"
+                       CtxMul _ (Lit 10) _  → "tren"
+                       _                    → "tre"
+            )
+          , (4, forms "quarta"  "quarto"  "quattresimo" "quattro" "quattor" "quar")
+          , (5, forms "quinta"  "quinto"  "cinquesimo"  "cinque"  "quin"    "cinqu")
+          , (6, forms "sesta"   "sesto"   "seiesimo"    "sei"     "se"      "sess")
+          , (7, forms "settimo" "settimo" "settesimo"   "sette"   "sette"   "sett")
+          , (8, forms "ottave"  "ottavo"  "ottesimo"    "otto"    "otto"    "ott")
+          , (9, forms "nono"    "nono"    "novesimo"    "nove"    "nove"    "nov")
+          , (10, \c → case c of
+                        CtxAdd _ (Lit _) _ | isOutside R c → "dicesimo"
+                                           | otherwise     → "dici"
+                        -- Last vowel removed because of a phonetic rule:
+                        CtxMul _ (Lit _) (CtxAdd _ (Lit n) _)
+                            | n ∈ [1,8]                    → "t"
+                        CtxMul R (Lit _) _ | isOutside R c → "tesimo"
+                                           | otherwise     → "ta"
+                        _                  | isOutside R c → "decimo"
+                                           | otherwise     → "dieci"
+            )
+          , (20, \c → case c of
+                        _ | isOutside R c  → "ventesimo"
+                        CtxAdd _ (Lit n) _
+                          | n ∈ [1,8]      → "vent"
+                        _                  → "venti"
+            )
+          , ( 100
+            , let f c = case c of
+                          _ | isOutside R c                        → "centesimo"
+                          CtxAdd _ (Lit 8)                      _  → "cent"
+                          CtxAdd _ (Lit 8 `Mul` Lit 10)         _  → "cent"
+                          CtxAdd _ (Lit 8 `Mul` Lit 10 `Add` _) _  → "cent"
+                          CtxMul _ (Lit _) c2                      → f c2
+                          _                                        → "cento"
+              in f
+            )
+          , (1000, \c → case c of
+                          _ | isOutside R c → "millesimo"
+                          CtxMul {}         → "mila"
+                          _                 → "mille"
+            )
+          ]
+          where
+            forms ∷ s → s → s → s → s → s → Ctx (Exp i) → s
+            forms fo1 o1 o2 n a m c =
+                case c of
+                  CtxEmpty
+                    | G.isFeminine inf → fo1
+                    | otherwise        → o1
+                  _ | isOutside R c    → o2
+                  CtxAdd _ (Lit 10) _  → a
+                  CtxMul _ (Lit 10) _  → m
+                  _                    → n
+
+bigNumSyms ∷ [(ℤ, Ctx (Exp i) → Text)]
+bigNumSyms =
+  [ (6, BN.forms "sest" "sex"    "ses"    "sexa"   "ses")
+  , (7, BN.forms "sett" "septen" "septem" "septua" "septin")
+  , (8, BN.forms "ott"  "otto"   "otto"   "otto"   "ottin")
+  ]
diff --git a/src/Text/Numeral/Language/JA.hs b/src/Text/Numeral/Language/JA.hs
--- a/src/Text/Numeral/Language/JA.hs
+++ b/src/Text/Numeral/Language/JA.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        ja
@@ -17,11 +16,21 @@
 -}
 
 module Text.Numeral.Language.JA
-    ( struct
+    ( -- * Language entry
+      kanji_entry
+    , daiji_entry
+    , on'yomi_entry
+    , preferred_entry
+      -- * Conversions
     , kanji_cardinal
     , daiji_cardinal
     , on'yomi_cardinal
     , preferred_cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    , daiji_bounds
     ) where
 
 
@@ -32,28 +41,32 @@
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.List     ( map )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
-import "base" Prelude       ( Num, Integral, (-) )
+import "base" Prelude       ( Num, Integral, (-), negate )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import "base-unicode-symbols" Data.Monoid.Unicode   ( (⊕) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc  ( dec )
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc  ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- JA
 --------------------------------------------------------------------------------
 
-{-
-Sources:
-  http://en.wikipedia.org/wiki/Japanese_numerals
-  http://www.guidetojapanese.org/numbers.html
--}
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1       = Just "ja"
+    , entIso639_2       = ["jpn"]
+    , entIso639_3       = Just "jpn"
+    , entNativeNames    = ["日本語"]
+    , entEnglishName    = Just "Japanese"
+    }
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β) ⇒ α → β
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β) ⇒ α → β
 struct = pos
        $ fix
        $ findRule (   0, lit             )
@@ -66,17 +79,32 @@
               )
              (dec 72 - 1)
 
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 72 - 1 in (negate x, x)
 
+daiji_bounds ∷ (Integral α) ⇒ (α, α)
+daiji_bounds = let x = dec 4 - 1 in (negate x, x)
+
+
 --------------------------------------------------------------------------------
 -- Kanji
 --------------------------------------------------------------------------------
 
-kanji_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-kanji_cardinal = kanji_cardinal_repr ∘ struct
+kanji_entry ∷ Entry
+kanji_entry = entry
+    { entVariant  = Just "kanji"
+    , entCardinal = Just Conversion
+                    { toNumeral   = kanji_cardinal
+                    , toStructure = struct
+                    }
+    }
 
-kanji_cardinal_repr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+kanji_cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+kanji_cardinal inf = kanji_cardinal_repr inf ∘ struct
+
+kanji_cardinal_repr ∷ i → Exp i → Maybe Text
 kanji_cardinal_repr = render defaultRepr
-                      { reprValue = \n → M.lookup n syms
+                      { reprValue = \_ n → M.lookup n syms
                       , reprAdd   = Just $ \_ _ _ → ""
                       , reprMul   = Just $ \_ _ _ → ""
                       , reprNeg   = Just $ \_ _   → "マイナス"
@@ -121,12 +149,21 @@
 -- Daiji
 --------------------------------------------------------------------------------
 
-daiji_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-daiji_cardinal = daiji_cardinal_repr ∘ struct
+daiji_entry ∷ Entry
+daiji_entry = entry
+    { entVariant  = Just "daiji"
+    , entCardinal = Just Conversion
+                    { toNumeral   = daiji_cardinal
+                    , toStructure = struct
+                    }
+    }
 
-daiji_cardinal_repr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+daiji_cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+daiji_cardinal inf = daiji_cardinal_repr inf ∘ struct
+
+daiji_cardinal_repr ∷ i → Exp i → Maybe Text
 daiji_cardinal_repr = render defaultRepr
-                      { reprValue = \n → M.lookup n syms
+                      { reprValue = \_ n → M.lookup n syms
                       , reprAdd   = Just $ \_ _ _ → ""
                       , reprMul   = Just $ \_ _ _ → ""
                       , reprNeg   = Just $ \_ _   → "マイナス"
@@ -155,9 +192,9 @@
 -- Generic reading
 --------------------------------------------------------------------------------
 
-generic_repr ∷ (Monoid s, IsString s) ⇒ s → s → Repr s
+generic_repr ∷ Text → Text → Repr i
 generic_repr four seven = defaultRepr
-                          { reprValue = \n → M.lookup n syms
+                          { reprValue = \_ n → M.lookup n syms
                           , reprAdd   = Just $ \_ _ _ → " "
                           , reprMul   = Just $ \_ _ _ → ""
                           , reprNeg   = Just $ \_ _   → "mainasu "
@@ -205,19 +242,37 @@
 -- On'yomi
 --------------------------------------------------------------------------------
 
-on'yomi_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-on'yomi_cardinal = on'yomi_cardinal_repr ∘ struct
+on'yomi_entry ∷ Entry
+on'yomi_entry = entry
+    { entVariant  = Just "on'yomi"
+    , entCardinal = Just Conversion
+                    { toNumeral   = on'yomi_cardinal
+                    , toStructure = struct
+                    }
+    }
 
-on'yomi_cardinal_repr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
-on'yomi_cardinal_repr = render $ generic_repr "shi" "shichi"
+on'yomi_cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+on'yomi_cardinal inf = on'yomi_cardinal_repr inf ∘ struct
 
+on'yomi_cardinal_repr ∷ i → Exp i → Maybe Text
+on'yomi_cardinal_repr = render (generic_repr "shi" "shichi")
 
+
 --------------------------------------------------------------------------------
 -- Preferred reading
 --------------------------------------------------------------------------------
 
-preferred_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-preferred_cardinal = preferred_cardinal_repr ∘ struct
+preferred_entry ∷ Entry
+preferred_entry = entry
+    { entVariant  = Just "preferred"
+    , entCardinal = Just Conversion
+                    { toNumeral   = preferred_cardinal
+                    , toStructure = struct
+                    }
+    }
 
-preferred_cardinal_repr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
-preferred_cardinal_repr = render $ generic_repr "yon" "nana"
+preferred_cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+preferred_cardinal inf = preferred_cardinal_repr inf ∘ struct
+
+preferred_cardinal_repr ∷ i → Exp i → Maybe Text
+preferred_cardinal_repr = render (generic_repr "yon" "nana")
diff --git a/src/Text/Numeral/Language/LA.hs b/src/Text/Numeral/Language/LA.hs
--- a/src/Text/Numeral/Language/LA.hs
+++ b/src/Text/Numeral/Language/LA.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        la
@@ -17,8 +16,14 @@
 -}
 
 module Text.Numeral.Language.LA
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -30,32 +35,40 @@
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.List     ( concat )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
 import "base" Prelude       ( Integral, Num, (+) )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import "base-unicode-symbols" Data.List.Unicode     ( (∈) )
 import "base-unicode-symbols" Data.Ord.Unicode      ( (≤) )
 import "base-unicode-symbols" Data.Monoid.Unicode   ( (⊕) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- LA
 --------------------------------------------------------------------------------
 
-{-
-Sources:
-  http://www.informalmusic.com/latinsoc/latnum.html
-  http://www.sf.airnet.ne.jp/~ts/language/number/latin.html
--}
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "la"
+    , entIso639_2    = ["lat"]
+    , entIso639_3    = Just "lat"
+    , entNativeNames = ["Latine"]
+    , entEnglishName = Just "Latin"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Sub β, C.Mul β) ⇒ α → β
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Sub β, E.Mul β) ⇒ α → β
 struct = checkPos
        $ fix
        $ findRule ( 0, lit)
@@ -73,9 +86,12 @@
                   )
                   1000
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (0, 1000)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprAdd   = Just (⊞)
                , reprMul   = Just (⊡)
                , reprSub   = Just $ \_ _ _ → "dē"
diff --git a/src/Text/Numeral/Language/LLD.hs b/src/Text/Numeral/Language/LLD.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/LLD.hs
@@ -0,0 +1,131 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        lld
+
+[@Native name@]     Ladin
+
+[@English name@]    Ladin
+-}
+
+module Text.Numeral.Language.LLD
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    ) where
+
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Data.Bool     ( otherwise )
+import "base" Data.Function ( ($), const )
+import "base" Data.Maybe    ( Maybe(Just) )
+import "base" Prelude       ( Integral, (-), negate )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Data.Bool.Unicode     ( (∧), (∨) )
+import "base-unicode-symbols" Data.Eq.Unicode       ( (≡), (≢) )
+import "base-unicode-symbols" Data.Ord.Unicode      ( (≤) )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum  as BN
+import qualified "this" Text.Numeral.Exp     as E
+import qualified "this" Text.Numeral.Grammar as G
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "this" Text.Numeral.Language.FUR ( struct )
+import "this" Text.Numeral.Render.Utils ( addCtx, mulCtx )
+import "text" Data.Text ( Text )
+
+
+--------------------------------------------------------------------------------
+-- LLD
+--------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_3    = Just "lld"
+    , entNativeNames = ["Ladin"]
+    , entEnglishName = Just "Ladin"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
+
+cardinal ∷ (G.Masculine i, G.Feminine i, Integral α, E.Scale α)
+         ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 12 - 1 in (negate x, x)
+
+cardinalRepr ∷ (G.Feminine i, G.Masculine i) ⇒ i → Exp i → Maybe Text
+cardinalRepr = render defaultRepr
+               { reprValue = \inf n → M.lookup n (syms inf)
+               , reprAdd   = Just (⊞)
+               , reprMul   = Just (⊡)
+               , reprScale = BN.pelletierRepr
+                               (BN.quantityName "ilion"  "ilion")
+                               (BN.quantityName "iliard" "iliard")
+                               []
+               }
+    where
+      (             Lit 20  ⊞ Lit n) _ | n ≢ 1 ∧          n ≢ 8  = "e"
+      ((Lit t `Mul` Lit 10) ⊞ Lit n) _ | n ≢ 1 ∧ (t ≡ 3 ∨ n ≢ 8) = "e"
+      (         Lit 100  ⊞ _) _ = "e"
+      ((_ `Mul` Lit 100) ⊞ _) _ = "e"
+      ((_ `Mul` Scale{}) ⊞ _) _ = "e"
+      (_                 ⊞ _) _ = ""
+
+      (_ ⊡ Scale {}) _ = " "
+      (_ ⊡ _       ) _ = ""
+
+      syms inf =
+          M.fromList
+          [ (0, const "zero")
+          , (1, addCtx 10 "un"
+                $ \c → case c of
+                         _ | G.isFeminine inf → "una"
+                           | otherwise        → "un"
+            )
+          , (2, addCtx 10 "do"
+                $ \c → case c of
+                         _ | G.isFeminine inf → "does"
+                           | otherwise        → "doi"
+            )
+          , (3, addCtx 10 "tre"   $ mulCtx 10 "tr"   $ const "trei")
+          , (4, addCtx 10 "cator" $ mulCtx 10 "car"  $ const "cater")
+          , (5, addCtx 10 "chin"  $ mulCtx 10 "cinc" $ const "cinch")
+          , (6, addCtx 10 "sei"   $ mulCtx 10 "sess" $ const "sies")
+          , (7, const "set")
+          , (8, addCtx 10 "dot" $ const "ot")
+          , (9, mulCtx 10 "non" $ const "nuef")
+          , (10, \c → case c of
+                        CtxAdd _ (Lit n) _
+                            | n ≤ 6 → "desc"
+                            | n ≡ 7 → "dejes"
+                            | n ≤ 9 → "deje"
+                        CtxMul _ (Lit 3) (CtxAdd {}) → "ent"
+                        CtxMul _ (Lit 3) _ → "enta"
+                        CtxMul _ (Lit _) (CtxAdd {}) → "ant"
+                        CtxMul _ (Lit _) _ → "anta"
+                        _ → "diesc"
+            )
+          , (20, const "vint")
+          , (100, mulCtx 6 "çent" $ const "cent")
+          , (1000, const "mile")
+          ]
diff --git a/src/Text/Numeral/Language/MG.hs b/src/Text/Numeral/Language/MG.hs
--- a/src/Text/Numeral/Language/MG.hs
+++ b/src/Text/Numeral/Language/MG.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        mg
@@ -17,8 +16,14 @@
 -}
 
 module Text.Numeral.Language.MG
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -29,40 +34,50 @@
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.List     ( map )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
 import "base" Data.Ord      ( (<) )
-import "base" Data.String   ( IsString )
 import "base" Prelude       ( Integral, (-) )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 -------------------------------------------------------------------------------
 -- MG
 -------------------------------------------------------------------------------
 
-{-
-Sources:
-  http://en.wikipedia.org/wiki/Malagasy_language
-  http://www.sf.airnet.ne.jp/~ts/language/number/malagasy.html
--}
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "mg"
+    , entIso639_2    = ["mlg"]
+    , entIso639_3    = Just "mlg"
+    , entEnglishName = Just "Malagasy"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ α → β
 struct = checkPos
        $ fix
        $ findRule (0, lit)
                   [(n, step n 10 L L) | n ← map dec [1..6]]
                   (dec 7 - 1)
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (0, dec 7 - 1)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprAdd   = Just (⊞)
                , reprMul   = Just (⊡)
                }
diff --git a/src/Text/Numeral/Language/NL.hs b/src/Text/Numeral/Language/NL.hs
--- a/src/Text/Numeral/Language/NL.hs
+++ b/src/Text/Numeral/Language/NL.hs
@@ -1,8 +1,8 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE PackageImports      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE UnicodeSyntax       #-}
 
 {-|
 [@ISO639-1@]        nl
@@ -17,59 +17,116 @@
 -}
 
 module Text.Numeral.Language.NL
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+    , ordinal
+    , partitive
+    , multiplicative
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
+
 --------------------------------------------------------------------------------
 -- Imports
 --------------------------------------------------------------------------------
 
-import "base" Data.Bool     ( otherwise )
+import "base" Control.Monad ( return )
+import "base" Data.Bool     ( Bool, otherwise )
 import "base" Data.Function ( ($), const, fix )
+import "base" Data.Functor  ( fmap )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
 import "base" Data.Ord      ( (<) )
-import "base" Data.String   ( IsString )
-import "base" Prelude       ( Integral, (-) )
+import "base" Prelude       ( Integral, (-), negate )
+import "base-unicode-symbols" Data.Bool.Unicode     ( (∧), (∨) )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import "base-unicode-symbols" Data.List.Unicode     ( (∈) )
+import "base-unicode-symbols" Data.Monoid.Unicode   ( (⊕) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
-import qualified "numerals-base" Text.Numeral.BigNum as BN ( rule, pelletierRepr )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum  as BN
+import qualified "this" Text.Numeral.Exp     as E
+import qualified "this" Text.Numeral.Grammar as G
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- NL
 --------------------------------------------------------------------------------
 
-cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1       = Just "nl"
+    , entIso639_2       = ["dut"]
+    , entIso639_3       = Just "nld"
+    , entNativeNames    = ["Nederlands"]
+    , entEnglishName    = Just "Dutch"
+    , entCardinal       = Just Conversion
+                          { toNumeral   = cardinal
+                          , toStructure = struct
+                          }
+    , entOrdinal        = Just Conversion
+                          { toNumeral   = ordinal
+                          , toStructure = struct
+                          }
+    , entPartitive      = Just Conversion
+                          { toNumeral   = partitive
+                          , toStructure = \(n, d) → E.frac (struct n) (struct d)
+                          }
+    , entMultiplicative = Just Conversion
+                          { toNumeral   = multiplicative
+                          , toStructure = struct
+                          }
+    }
 
-struct ∷ ( Integral α, C.Scale α
-         , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β
+cardinal ∷ (G.Plural i, G.Dative i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+ordinal ∷ (Integral α, E.Scale α) ⇒ i → α → Maybe Text
+ordinal inf = ordinalRepr "eerste" inf ∘ struct
+
+partitive ∷ ( G.Singular i, G.Plural i, G.NoCase i, G.Dative i
+            , Integral α, E.Scale α
+            )
+          ⇒ i → (α, α) → Maybe Text
+partitive inf (n, d) = do
+  n' ← cardinal (G.noCase $ G.singular inf) n
+  d' ← ordinalRepr "éénde" inf $ struct d
+  return $ n' ⊕ " " ⊕ d'
+
+multiplicative ∷ ( G.Singular i, G.Plural i, G.NoCase i, G.Dative i
+                 , Integral α, E.Scale α
+                 )
+               ⇒ i → α → Maybe Text
+multiplicative inf = fmap (⊕ "maal") ∘ cardinal (G.noCase $ G.singular inf)
+
+struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
          )
        ⇒ α → β
-struct = pos $ fix $ rule `combine` pelletierScale R L BN.rule
+struct = pos
+       $ fix
+       $ findRule (   0, lit               )
+                [ (  13, add    10      L  )
+                , (  20, mul    10      L L)
+                , ( 100, step  100   10 R L)
+                , (1000, step 1000 1000 R L)
+                ]
+                  (dec 6 - 1)
+         `combine` pelletierScale R L BN.rule
 
-rule ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ Rule α β
-rule = findRule (   0, lit               )
-              [ (  13, add    10      L  )
-              , (  20, mul    10      L L)
-              , ( 100, step  100   10 R L)
-              , (1000, step 1000 1000 R L)
-              ]
-                (dec 6 - 1)
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 60000 - 1 in (negate x, x)
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
-cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
-               , reprScale = BN.pelletierRepr "iljoen" "iljoen"
-                                              "iljard" "iljard"
-                                              []
-               , reprAdd   = Just (⊞)
+genericRepr ∷ Repr i
+genericRepr = defaultRepr
+               { reprAdd   = Just (⊞)
                , reprMul   = Just $ \_ _ _ → ""
                , reprNeg   = Just $ \_ _   → "min "
                }
@@ -80,33 +137,132 @@
                     | otherwise  = ""
       (_     ⊞ _) _              = ""
 
-      syms =
+cardinalRepr ∷ ∀ i. (G.Plural i, G.Dative i) ⇒ i → Exp i → Maybe Text
+cardinalRepr = render genericRepr
+               { reprValue = \inf n → M.lookup n (syms inf)
+               , reprScale = BN.pelletierRepr (\i c → if doPlural i c then "iljoenen" else "iljoen")
+                                              (\i c → if doPlural i c then "iljarden" else "iljard")
+                                              []
+               }
+    where
+      doPlural ∷ i → Ctx (Exp i) → Bool
+      doPlural inf ctx = (G.isPlural inf ∨ G.isDative inf) ∧ isOutside R ctx
+
+      syms inf =
           M.fromList
           [ (0, const "nul")
-          , (1, const "een")
-          , (2, tenForms "twee" "twin")
-          , (3, tenForms "drie" "der")
-          , (4, tenForms "vier" "veer")
-          , (5, const "vijf")
-          , (6, const "zes")
-          , (7, const "zeven")
+          , (1, pluralDative "één" "éénen" "éénen")
+          , (2, forms "twee" "twin" "tweeën" "tweeën")
+          , (3, forms "drie" "der"  "drieën" "drieën")
+          , (4, forms "vier" "veer" "vieren" "vieren")
+          , (5, pluralDative "vijf"  "vijven" "vijven")
+          , (6, pluralDative "zes"   "zessen" "zessen")
+          , (7, pluralDative "zeven" "zevens" "zevenen")
           , (8, \c → case c of
                        CtxMul _ (Lit 10) _ → "tach"
+                       CtxAdd _ (Lit 10) _ → "ach"
+                       _ | dativeForm c
+                         ∨ pluralForm c    → "achten"
+                         | otherwise       → "acht"
+            )
+          , (9, pluralDative "negen" "negens" "negenen")
+          , (10, \c → case c of
+                        CtxAdd R _ _
+                          | dativeForm c → "tienen"
+                          | pluralForm c → "tiens"
+                        CtxMul R _ _
+                          | dativeForm c → "tigen"
+                          | pluralForm c → "tigs"
+                          | otherwise    → "tig"
+                        _ | dativeForm c
+                          ∨ pluralForm c → "tienen"
+                          | otherwise    → "tien"
+            )
+          , (  11, pluralDative "elf"     "elven"     "elven")
+          , (  12, pluralDative "twaalf"  "twaalven"  "twaalven")
+          , ( 100, pluralDative "honderd" "honderden" "honderden")
+          , (1000, pluralDative "duizend" "duizenden" "duizenden")
+          ]
+          where
+            pluralDative ∷ s → s → s → Ctx (Exp i) → s
+            pluralDative  o p d ctx
+                | pluralForm ctx = p
+                | dativeForm ctx = d
+                | otherwise      = o
+
+            dativeForm ∷ Ctx (Exp i) → Bool
+            dativeForm ctx = G.isDative inf ∧ isOutside R ctx
+
+            pluralForm ∷ Ctx (Exp i) → Bool
+            pluralForm ctx = G.isPlural inf ∧ isOutside R ctx
+
+            forms ∷ s -- ^ Normal form.
+                  → s -- ^ Added to, or multiplied with ten.
+                  → s -- ^ Plural form.
+                  → s -- ^ Dative form.
+                  → Ctx (Exp i)
+                  → s
+            forms n t p d ctx =
+                case ctx of
+                  CtxMul _ (Lit 10) _ → t
+                  CtxAdd _ (Lit 10) _ → t
+                  _ | dativeForm ctx  → d
+                    | pluralForm ctx  → p
+                    | otherwise       → n
+
+ordinalRepr ∷ Text → i → Exp i → Maybe Text
+ordinalRepr one =
+    render genericRepr
+           { reprValue = \_ n → M.lookup n syms
+           , reprScale = BN.pelletierRepr ( BN.ordQuantityName "iljoen" "iljoenste"
+                                                               "iljoen" "iljoenste"
+                                          )
+                                          ( BN.ordQuantityName "iljard" "iljardste"
+                                                               "iljard" "iljardste"
+                                          )
+                                          []
+           }
+    where
+      syms =
+          M.fromList
+          [ (0, const "nulde")
+          , (1, \c → case c of
+                       CtxEmpty          → one
+                       _ | isOutside R c → "éénde"
+                         | otherwise     → "één"
+            )
+          , (2, forms "tweede"  "twee"  "twin")
+          , (3, forms "derde"   "drie"  "der")
+          , (4, forms "vierde"  "vier"  "veer")
+          , (5, forms "vijfde"  "vijf"  "vijf")
+          , (6, forms "zesde"   "zes"   "zes")
+          , (7, forms "zevende" "zeven" "zeven")
+          , (8, \c → case c of
+                       _ | isOutside R c → "achtste"
+                       CtxMul _ (Lit 10) _ → "tach"
                        CtxAdd _ (Lit _)  _ → "ach"
                        _                   → "acht"
             )
-          , (9, const "negen")
+          , (9, forms "negende" "negen" "negen")
           , (10, \c → case c of
-                        CtxMul R _ _ → "tig"
-                        _            → "tien"
+                        CtxMul R _ _ | isOutside R c → "tigste"
+                                     | otherwise     → "tig"
+                        _            | isOutside R c → "tiende"
+                                     | otherwise     → "tien"
             )
-          , (11, const "elf")
-          , (12, const "twaalf")
-          , (100, const "honderd")
-          , (1000, const "duizend")
+          , (11, \c → if isOutside R c then "elfde"    else "elf")
+          , (12, \c → if isOutside R c then "twaalfde" else "twaalf")
+          , (100,  \c → if isOutside R c then "honderdste" else "honderd")
+          , (1000, \c → if isOutside R c then "duizendste" else "duizend")
           ]
 
-      tenForms n t ctx = case ctx of
-                           CtxMul _ (Lit 10) _ → t
-                           CtxAdd _ (Lit _)  _ → t
-                           _                   → n
+      forms ∷ s -- ^ Ordinal form.
+            → s -- ^ Cardinal form.
+            → s -- ^ Added to, or multiplied with, ten.
+            → Ctx (Exp i)
+            → s
+      forms o c t ctx = case ctx of
+                          _ | isOutside R ctx → o
+                          CtxMul _ (Lit 10) _ → t
+                          CtxAdd _ (Lit _)  _ → t
+                          _                   → c
diff --git a/src/Text/Numeral/Language/NO.hs b/src/Text/Numeral/Language/NO.hs
--- a/src/Text/Numeral/Language/NO.hs
+++ b/src/Text/Numeral/Language/NO.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        nb
@@ -17,68 +16,107 @@
 -}
 
 module Text.Numeral.Language.NO
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
+
 -------------------------------------------------------------------------------
 -- Imports
 -------------------------------------------------------------------------------
 
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
-import "base" Prelude       ( Integral )
+import "base" Prelude       ( Integral, (-), negate )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum as BN
+import qualified "this" Text.Numeral.Exp    as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 -------------------------------------------------------------------------------
 -- NO
 -------------------------------------------------------------------------------
 
--- Sources:
---   http://en.wikibooks.org/wiki/Norwegian_Numbers
---   http://www.sf.airnet.ne.jp/~ts/language/number/norwegian.html
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "nb"
+    , entIso639_2    = ["nob"]
+    , entIso639_3    = Just "nob"
+    , entNativeNames = ["Bokmål"]
+    , entEnglishName = Just "Norwegian Bokmål"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β) ⇒ α → β
+struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
+         )
+       ⇒ α → β
 struct = pos
        $ fix
-       $ findRule (  0, lit            )
-                [ ( 13, add   10    L  )
-                , ( 20, lit            )
-                , ( 21, add   20    R  )
-                , ( 30, mul   10    R L)
-                , (100, step 100 10 R L)
+       $ findRule (   0, lit               )
+                [ (  13, add    10      L  )
+                , (  20, lit               )
+                , (  21, add    20      R  )
+                , (  30, mul    10      R L)
+                , ( 100, step  100   10 R L)
+                , (1000, step 1000 1000 R L)
                 ]
-                  1000
+                  (dec 6 - 1)
+         `combine` pelletierScale R L BN.rule
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 60000 - 1 in (negate x, x)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
-               , reprAdd   = Just $ \_ _ _ → ""
-               , reprMul   = Just $ \_ _ _ → ""
+               { reprValue = \_ n → M.lookup n syms
+               , reprScale = BN.scaleRepr (BN.quantityName "illion" "illioner") []
+               , reprAdd   = Just (⊞)
+               , reprMul   = Just (⊡)
                , reprNeg   = Just $ \_ _   → "minus "
                }
     where
+      (Lit 100  ⊞ _) _ = " "
+      (Lit 1000 ⊞ _) _ = " "
+      (_        ⊞ _) _ = ""
+
+      (_ ⊡ Lit 10  ) _ = ""
+      (_ ⊡ Lit 1000) _ = ""
+      (_ ⊡ _       ) _ = " "
+
       syms =
           M.fromList
           [ (0,  const "null")
-          , (1,  const "en")
+          , (1,  \c → case c of
+                        CtxEmpty → "én"
+                        _        → "en"
+            )
           , (2,  const "to")
-          , (3,  ten   "tre"  "tret" "tret")
-          , (4,  ten   "fire" "fjor" "før")
+          , (3,  tenForms   "tre"  "tret" "tret")
+          , (4,  tenForms   "fire" "fjor" "før")
           , (5,  const "fem")
           , (6,  const "seks")
-          , (7,  ten   "syv"  "syt"  "syt")
-          , (8,  ten   "åtte" "at"   "åt")
-          , (9,  ten   "ni"   "nit"  "nit")
+          , (7,  tenForms   "sju"  "syt"  "syt")
+          , (8,  tenForms   "åtte" "at"   "åt")
+          , (9,  tenForms   "ni"   "nit"  "nit")
           , (10, \c → case c of
                         CtxAdd {} → "ten"
                         _         → "ti"
@@ -90,7 +128,9 @@
           , (1000, const "tusen")
           ]
 
-      ten n a m = \c → case c of
-                         CtxAdd _ (Lit 10) _ → a
-                         CtxMul {}           → m
-                         _                   → n
+      tenForms n a m = \c → case c of
+                              CtxAdd _ (Lit 10  ) _ → a
+                              CtxMul _ (Lit 100 ) _ → n
+                              CtxMul _ (Lit 1000) _ → n
+                              CtxMul {}             → m
+                              _                     → n
diff --git a/src/Text/Numeral/Language/NQM.hs b/src/Text/Numeral/Language/NQM.hs
--- a/src/Text/Numeral/Language/NQM.hs
+++ b/src/Text/Numeral/Language/NQM.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        -
@@ -17,8 +16,14 @@
 -}
 
 module Text.Numeral.Language.NQM
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -28,23 +33,34 @@
 
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
 import "base" Prelude       ( Integral )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- NQM
 --------------------------------------------------------------------------------
 
-cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_3    = Just "nqm"
+    , entEnglishName = Just "Ndom"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ α → β
 struct = checkPos
        $ fix
        $ findRule (  1, lit       )
@@ -58,9 +74,12 @@
                 ]
                    107
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (1, 107)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprAdd   = Just $ \_ _ _ → " abo "
                , reprMul   = Just (⊡)
                }
diff --git a/src/Text/Numeral/Language/OJ.hs b/src/Text/Numeral/Language/OJ.hs
--- a/src/Text/Numeral/Language/OJ.hs
+++ b/src/Text/Numeral/Language/OJ.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        oj
@@ -17,39 +16,54 @@
 -}
 
 module Text.Numeral.Language.OJ
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
+
 --------------------------------------------------------------------------------
 -- Imports
 --------------------------------------------------------------------------------
 
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
 import "base" Prelude       ( Integral )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- OJ
 --------------------------------------------------------------------------------
 
-{-
-Sources:
-  http://www.sf.airnet.ne.jp/~ts/language/number/ojibwa.html
-  http://www.languagesandnumbers.com/how-to-count-in-ojibwa/en/oji/
--}
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "oj"
+    , entIso639_2    = ["oji"]
+    , entIso639_3    = Just "oji"
+    , entNativeNames = ["ᐊᓂᔑᓈᐯᒧᐎᓐ", "Anishinaabemowin"]
+    , entEnglishName = Just "Ojibwe"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β)
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β)
        ⇒ α → β
 struct = checkPos
        $ fix
@@ -60,9 +74,12 @@
                 ]
                    1999
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (1, 1999)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprAdd   = Just $ \_ _ _ → " shaa "
                , reprMul   = Just $ \_ _ _ → ""
                }
@@ -90,7 +107,7 @@
           , (1000, const "mdaaswaak")
           ]
 
-      forms ∷ s → s → s → Ctx Exp → s
+      forms ∷ s → s → s → Ctx (Exp i) → s
       forms o t h = \c → case c of
                            CtxMul _ (Lit 10)  _ → t
                            CtxMul _ (Lit 100) _ → h
diff --git a/src/Text/Numeral/Language/PDC.hs b/src/Text/Numeral/Language/PDC.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/PDC.hs
@@ -0,0 +1,156 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        -
+
+[@ISO639-2@]        -
+
+[@ISO639-3@]        pdc
+
+[@Native name@]     Pennsilfaanisch Deitsch
+
+[@English name@]    Pennsylvania German
+-}
+
+module Text.Numeral.Language.PDC
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    ) where
+
+
+-------------------------------------------------------------------------------
+-- Imports
+-------------------------------------------------------------------------------
+
+import "base" Data.Bool     ( otherwise )
+import "base" Data.Function ( ($), const, fix )
+import "base" Data.Maybe    ( Maybe(Nothing, Just) )
+import "base" Prelude       ( Integral, (-), negate )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Data.Ord.Unicode      ( (≤) )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum as BN
+import qualified "this" Text.Numeral.Exp    as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
+
+
+-------------------------------------------------------------------------------
+-- PDC
+-------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Nothing
+    , entIso639_2    = []
+    , entIso639_3    = Just "pdc"
+    , entNativeNames = ["Pennsilfaanisch Deitsch"]
+    , entEnglishName = Just "Pennsylvania German"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    , entOrdinal     = Nothing
+    }
+
+cardinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
+         )
+       ⇒ α → β
+struct = pos
+       $ fix
+       $ findRule (   0, lit       )
+                [ (  13, add 10 L  )
+                , (  20, mul 10 L L)
+                , ( 100, step1 100    10 R L)
+                , (1000, step1 1000 1000 R L)
+                ]
+                  (dec 6 - 1)
+         `combine` pelletierScale1 R L BN.rule
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (0, dec 9 - 1)
+
+genericRepr ∷ Repr i
+genericRepr = defaultRepr
+              { reprAdd   = Just (⊞)
+              , reprMul   = Just (⊡)
+              , reprNeg   = Just $ \_ _ → "minus "
+              }
+    where
+      (Lit n ⊞ (_ `Mul` Lit 10)) _ | n ≤ 9 = "un"
+      ((Lit _ `Mul` Lit 100) ⊞ Lit _ ) _ = " un "
+      (_ ⊞ Lit 10) _ = ""
+      (_ ⊞ _     ) _ = " "
+
+      (_ ⊡ Lit 10) _ = ""
+      (_ ⊡ _)      _ = " "
+
+
+cardinalRepr ∷ i → Exp i → Maybe Text
+cardinalRepr = render genericRepr
+               { reprValue = \_ n → M.lookup n syms
+               , reprScale = BN.pelletierRepr (BN.quantityName "illyon"  "illyon")
+                                              (BN.quantityName "illyard" "illyard")
+                                              []
+               }
+    where
+      syms =
+          M.fromList
+          [ (0, const "null")
+          , (1, \c → case c of
+                       CtxAdd L _ _  → "een"
+                       CtxMul _ _ _  → "en"
+                       _             → "eens"
+            )
+          , (2, \c → case c of
+                       CtxMul _ (Lit 10) _ → "zwan"
+                       _                   → "zwee"
+            )
+          , (3, const "drei")
+          , (4, \c → case c of
+                       CtxAdd _ (Lit 10) _ → "va"
+                       CtxMul _ (Lit 10) _ → "va"
+                       _                   → "vier"
+            )
+          , (5, \c → case c of
+                       CtxAdd _ (Lit 10) _ → "fuff"
+                       CtxMul _ (Lit 10) _ → "fuff"
+                       _                   → "fimf"
+            )
+          , (6, \c → case c of
+                       CtxAdd _ (Lit 10) _ → "sech"
+                       CtxMul _ (Lit 10) _ → "sech"
+                       _                   → "sex"
+            )
+          , (7, const "siwwe")
+          , (8, const "acht")
+          , (9, const "nein")
+          , (10, \c → case c of
+                        CtxAdd _ (Lit _) _ → "zeh"
+                        CtxMul _ (Lit 3) _ → "ssich"
+                        CtxMul R (Lit n) _ | n ≤ 3     → "sich"
+                                           | otherwise → "zich"
+                        _                  → "zehe"
+            )
+          , (11, const "elf")
+          , (12, const "zwelf")
+          , (100, const "hunnert")
+          , (1000, const "dausend")
+          ]
+
diff --git a/src/Text/Numeral/Language/PL.hs b/src/Text/Numeral/Language/PL.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Language/PL.hs
@@ -0,0 +1,165 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
+
+{-|
+[@ISO639-1@]        pl
+
+[@ISO639-2@]        pol
+
+[@ISO639-3@]        pol
+
+[@Native name@]     język polski
+
+[@English name@]    Polish
+-}
+
+module Text.Numeral.Language.PL
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
+    ) where
+
+
+-------------------------------------------------------------------------------
+-- Imports
+-------------------------------------------------------------------------------
+
+import "base" Data.Bool     ( otherwise )
+import "base" Data.Function ( ($), const, fix )
+import "base" Data.Maybe    ( Maybe(Just) )
+import "base" Prelude       ( Integral, (-), negate )
+import "base-unicode-symbols" Data.Eq.Unicode       ( (≡) )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Data.Ord.Unicode      ( (≥), (≤) )
+import qualified "containers" Data.Map as M ( fromList, lookup )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum as BN
+import qualified "this" Text.Numeral.Exp    as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
+
+-------------------------------------------------------------------------------
+-- PL
+-------------------------------------------------------------------------------
+
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "pl"
+    , entIso639_2    = ["pol"]
+    , entIso639_3    = Just "pol"
+    , entNativeNames = ["język polski"]
+    , entEnglishName = Just "Polish"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
+
+-- | liczebniki główne
+cardinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
+         )
+       ⇒ α → β
+struct = pos
+       $ fix
+       $ findRule (   0, lit               )
+                [ (  11, add    10      L  )
+                , (  20, step   10   10 R L)
+                , ( 100, step  100   10 R L)
+                , (1000, step 1000 1000 R L)
+                ]
+                  (dec 6 - 1)
+         `combine` pelletierScale R L BN.rule
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 60000 - 1 in (negate x, x)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
+cardinalRepr = render defaultRepr
+               { reprValue = \_ n → M.lookup n syms
+               , reprScale = BN.pelletierRepr (quantityRepr "ilion"  "iliony"  "ilionów")
+                                              (quantityRepr "iliard" "iliardy" "iliardów")
+                                              []
+               , reprAdd   = Just (⊞)
+               , reprMul   = Just (⊡)
+               }
+    where
+      (Lit n ⊞ Lit 10) _ | n ≤ 9 = ""
+      (_     ⊞ _     ) _         = " "
+
+      (_ ⊡ Lit 10 ) _ = ""
+      (_ ⊡ Lit 100) _ = ""
+      (_ ⊡ _      ) _ = " "
+
+      quantityRepr ∷ Text → Text → Text → BN.PostfixRepr i
+      quantityRepr s p1 p2 _ ctx =
+          case ctx of
+            CtxMul _ (Lit 1) _ → s
+            CtxMul _ (Lit n) _ | n ≤ 4 → p1
+            CtxMul {}          → p2
+            _                  → s
+
+      syms =
+          M.fromList
+          [ (0,  const                         "zero")
+          , (1,  \c → case c of
+                        CtxAdd _ (Lit 10)  _ → "jede"
+                        _                    → "jeden"
+            )
+          , (2,  \c → case c of
+                        CtxMul _ (Lit 100) _ → "dwie"
+                        _                    → "dwa"
+            )
+          , (3, const                          "trzy")
+          , (4,  \c → case c of
+                        CtxAdd _ (Lit 10)  _ → "czter"
+                        CtxMul _ (Lit 10)  _ → "czter"
+                        _                    → "cztery"
+            )
+          , (5,  \c → case c of
+                        CtxAdd _ (Lit 10)  _ → "pięt"
+                        _                    → "pięć"
+            )
+          , (6,  \c → case c of
+                        CtxAdd _ (Lit 10)  _ → "szes"
+                        _                    → "sześć"
+            )
+          , (7,  const                         "siedem")
+          , (8,  const                         "osiem")
+          , (9,  \c → case c of
+                        CtxAdd _ (Lit 10)  _ → "dziewięt"
+                        _                    → "dziewięć"
+            )
+          , (10,  \c → case c of
+                         CtxAdd R (Lit n) _ | n ≤ 9 → "naście"
+                         CtxMul R (Lit n) _
+                             | n ≡ 2     → "dzieścia"
+                             | n ≥ 5     → "dziesiąt"
+                             | otherwise → "dzieści"
+                         _               → "dziesięć"
+            )
+          , (100, \c → case c of
+                         CtxMul _ (Lit n) _
+                             | n ≡ 2 → "ście"
+                             | n ≤ 4 → "sta"
+                             | n ≤ 9 → "set"
+                         _           → "sto"
+            )
+          , (1000, \c → case c of
+                          CtxMul _ (Lit n) _ | n ≤ 4 → "tysiące"
+                          CtxMul {}                  → "tysięcy"
+                          _                          → "tysiąc"
+            )
+          ]
diff --git a/src/Text/Numeral/Language/PT.hs b/src/Text/Numeral/Language/PT.hs
--- a/src/Text/Numeral/Language/PT.hs
+++ b/src/Text/Numeral/Language/PT.hs
@@ -1,8 +1,8 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        pt
@@ -17,8 +17,16 @@
 -}
 
 module Text.Numeral.Language.PT
-    ( cardinal
-    , struct
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+    , ordinal
+      -- * Structure
+    , cardinal_struct
+    , ordinal_struct
+      -- * Bounds
+    , bounds
     ) where
 
 -------------------------------------------------------------------------------
@@ -28,36 +36,59 @@
 import "base" Data.Bool     ( otherwise )
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
 import "base" Data.Ord      ( (<) )
-import "base" Data.String   ( IsString )
-import "base" Prelude       ( Integral, (-), Integer )
+import "base" Prelude       ( Integral, (-), negate )
 import "base-unicode-symbols" Data.Eq.Unicode       ( (≡) )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Data.List.Unicode     ( (∉) )
+import "base-unicode-symbols" Data.Monoid.Unicode   ( (⊕) )
 import "base-unicode-symbols" Data.Ord.Unicode      ( (≤) )
+import "base-unicode-symbols" Prelude.Unicode       ( ℤ )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.BigNum      as BN
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum  as BN
+import qualified "this" Text.Numeral.Exp     as E
+import           "this" Text.Numeral.Grammar as G
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 -------------------------------------------------------------------------------
 -- PT
 -------------------------------------------------------------------------------
 
--- Sources:
---   http://www.sonia-portuguese.com/text/numerals.htm
---   http://www.smartphrase.com/Portuguese/po_numbers_voc.shtml
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "pt"
+    , entIso639_2    = ["por"]
+    , entIso639_3    = Just "por"
+    , entNativeNames = ["Português"]
+    , entEnglishName = Just "Portuguese"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = cardinal_struct
+                       }
+    , entOrdinal     = Just Conversion
+                       { toNumeral   = ordinal
+                       , toStructure = ordinal_struct
+                       }
+    }
 
-cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (G.Feminine i, G.Masculine i, Integral α, E.Scale α)
+         ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ cardinal_struct
 
-struct ∷ ( Integral α, C.Scale α
-         , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β
+ordinal ∷ (G.Feminine i, G.Masculine i, G.Singular i, Integral α, E.Scale α)
+         ⇒ i → α → Maybe Text
+ordinal inf = ordinalRepr inf ∘ ordinal_struct
+
+cardinal_struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
+         , E.Inflection β, G.Masculine (E.Inf β)
          )
        ⇒ α → β
-struct = pos $ fix $ rule `combine` shortScale R L BN.rule
+cardinal_struct = pos $ fix $ rule `combine` shortScale1_pt
     where
       rule = findRule (   0, lit       )
                     [ (  11, add 10 L  )
@@ -66,11 +97,41 @@
                     , ( 100, step  100   10 R L)
                     , (1000, step 1000 1000 R L)
                     ]
-                    (dec 6 - 1)
+                      (dec 6 - 1)
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+ordinal_struct ∷ ( Integral α, E.Scale α
+                 , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
+                 , E.Inflection β, G.Masculine (E.Inf β)
+                 )
+                 ⇒ α → β
+ordinal_struct = pos $ fix $ rule `combine` shortScale1_pt
+    where
+      rule = findRule (   0, lit       )
+                    [ (  11, add 10 R  )
+                    , (  20, mul 10 R L)
+                    , ( 100, step  100   10 R L)
+                    , (1000, step 1000 1000 R L)
+                    ]
+                      (dec 6 - 1)
+
+-- | Like 'shortScale1' with the difference that all scale elements
+-- are masculine.
+shortScale1_pt ∷ ( Integral α, E.Scale α
+                , E.Unknown β, E.Lit β, E.Add β, E.Mul β, E.Scale β
+                , E.Inflection β, G.Masculine (E.Inf β)
+                )
+              ⇒ Rule α β
+shortScale1_pt = mulScale1_es 3 3 R L BN.rule
+    where
+      mulScale1_es = mulScale_ $ \f m s _ → masculineMul (f m) s
+      masculineMul x y = E.inflection (G.masculine) $ E.mul x y
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 60000 - 1 in (negate x, x)
+
+cardinalRepr ∷ (G.Feminine i) ⇒ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \inf n → M.lookup n (syms inf)
                , reprScale = shortScaleRepr
                , reprAdd   = Just (⊞)
                , reprMul   = Just (⊡)
@@ -88,18 +149,20 @@
       (_ ⊡ Lit 100) _ = ""
       (_ ⊡ _      ) _ = " "
 
-      syms =
+      syms inf =
           M.fromList
           [ (0, const "zero")
           , (1, \c → case c of
-                       CtxAdd _ (Lit 10) _ → "on"
-                       _                   → "um"
+                       CtxAdd _ (Lit 10) _  → "on"
+                       _ | G.isFeminine inf → "uma"
+                         | otherwise        → "um"
             )
           , (2, \c → case c of
                        CtxAdd _ (Lit 10)  _ → "do"
                        CtxMul _ (Lit 10)  _ → "vin"
                        CtxMul _ (Lit 100) _ → "duz"
-                       _                    → "dois"
+                       _ | G.isFeminine inf → "duas"
+                         | otherwise        → "dois"
             )
           , (3, \c → case c of
                        CtxAdd _ (Lit 10)  _ → "tre"
@@ -141,19 +204,105 @@
                         _                  → "dez"
             )
           , (100, \c → case c of
-                         CtxAdd {}       → "cento"
+                         CtxAdd {} → "cento"
                          CtxMul _ (Lit n) _
-                             | n ≤ 3     → "entos"
-                             | n ≡ 4     → "centos"
-                             | n ≡ 5     → "hentos"
-                             | otherwise → "centos"
-                         _               → "cem"
+                             | n ≤ 3 → if G.isFeminine inf then "entas"  else "entos"
+                             | n ≡ 5 → if G.isFeminine inf then "hentas" else "hentos"
+                             | n ≤ 9 → if G.isFeminine inf then "centas" else "centos"
+                             | otherwise → "cem"
+                         _ → "cem"
             )
           , (1000, const "mil")
           ]
 
-shortScaleRepr ∷ (IsString s, Monoid s)
-               ⇒ Integer → Integer → Exp → Ctx Exp → Maybe s
+ordinalRepr ∷ (G.Feminine i, G.Singular i) ⇒ i → Exp i → Maybe Text
+ordinalRepr = render defaultRepr
+              { reprValue = \inf n → M.lookup n (syms inf)
+              , reprScale = shortScaleRepr
+              , reprAdd   = Just (⊞)
+              , reprMul   = Just (⊡)
+              , reprNeg   = Just $ \_ _ → "menos "
+              }
+    where
+      (Lit _  ⊞ Lit 10) _ = ""
+      (_      ⊞ _     ) _ = " "
+
+      (_ ⊡ Lit 10 ) _ = ""
+      (_ ⊡ Lit 100) _ = ""
+      (_ ⊡ _      ) _ = " "
+
+      syms inf =
+          M.fromList
+          [ (0, const "zero")
+          , (1, \c → case c of
+                       _ → "primeir" ⊕ postFix
+            )
+          , (2, \c → case c of
+                       CtxMul _ (Lit 10)  _ → "vi"
+                       CtxMul _ (Lit 100) _ → "du"
+                       _                    → "segund" ⊕ postFix
+            )
+          , (3, \c → case c of
+                       CtxMul _ (Lit 10)  _ → "tri"
+                       CtxMul _ (Lit 100) _ → "tre"
+                       _                    → "terceir" ⊕ postFix
+            )
+          , (4, \c → case c of
+                       CtxMul _ (Lit 10)  _ → "quadra"
+                       CtxMul _ (Lit 100) _ → "quadrin"
+                       _                    → "quart" ⊕ postFix
+            )
+          , (5, \c → case c of
+                       CtxMul _ (Lit 10)  _ → "qüinqua"
+                       CtxMul _ (Lit 100) _ → "qüin"
+                       _                    → "quint" ⊕ postFix
+            )
+          , (6, \c → case c of
+                       CtxMul _ (Lit 10)  _ → "sexa"
+                       CtxMul _ (Lit 100) _ → "sex"
+                       _                    → "sext" ⊕ postFix
+            )
+          , (7, \c → case c of
+                       CtxMul _ (Lit 10)  _ → "septua"
+                       CtxMul _ (Lit 100) _ → "setin"
+                       _                    → "sétim" ⊕ postFix
+            )
+          , (8, \c → case c of
+                       CtxMul _ (Lit 10)  _ → "octo"
+                       CtxMul _ (Lit 100) _ → "octin"
+                       _                    → "oitav" ⊕ postFix
+            )
+          , (9, \c → case c of
+                       CtxMul _ (Lit 10)  _ → "nona"
+                       CtxMul _ (Lit 100) _ → "non"
+                       _                    → "non" ⊕ postFix
+            )
+          , (10, \c → case c of
+                        CtxAdd R (Lit _) _  → "ze"
+                        CtxMul R (Lit _) _
+                            | isOutside R c → "gésim" ⊕ postFix
+                            | otherwise     → "gésimo"
+                        _ | isOutside R c   → "décim" ⊕ postFix
+                          | otherwise       → "décimo"
+            )
+          , (100, \c → case c of
+                         CtxAdd {}         → "cento"
+                         CtxMul _ (Lit n) _
+                             | n ∉ [2,3,6] → "gentésim" ⊕ postFix
+                         _                 → "centésim" ⊕ postFix
+            )
+          , (1000, const $ "milésim" ⊕ postFix)
+          ]
+          where
+            postFix = if G.isFeminine inf
+                      then if G.isSingular inf
+                           then "a"
+                           else "as"
+                      else if G.isSingular inf
+                           then "o"
+                           else "os"
+
+shortScaleRepr ∷ i → ℤ → ℤ → Exp i → Ctx (Exp i) → Maybe Text
 shortScaleRepr =
-    BN.scaleRepr "ilhão" "ilhões"
+    BN.scaleRepr (BN.quantityName "ilhão" "ilhões")
                  [(4, BN.forms "quatr" "quator" "quator" "quatra" "quatri")]
diff --git a/src/Text/Numeral/Language/RU.hs b/src/Text/Numeral/Language/RU.hs
--- a/src/Text/Numeral/Language/RU.hs
+++ b/src/Text/Numeral/Language/RU.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        ru
@@ -17,8 +16,14 @@
 -}
 
 module Text.Numeral.Language.RU
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -28,37 +33,43 @@
 
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
 import "base" Data.Ord      ( (<), (>) )
-import "base" Data.String   ( IsString )
-import "base" Prelude       ( Integral, (-) )
+import "base" Prelude       ( Integral, (-), negate )
 import "base-unicode-symbols" Data.Eq.Unicode       ( (≡) )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import "base-unicode-symbols" Data.Ord.Unicode      ( (≤), (≥) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- RU
 --------------------------------------------------------------------------------
 
-{-
-Sources:
-  http://en.wikibooks.org/wiki/Russian/Numbers
-  http://russian.speak7.com/russian_numbers.htm
-  http://learningrussian.net/games_verbs_grammar3.php
-  http://www.waytorussia.net/WhatIsRussia/Russian/Part1a.html
--}
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "ru"
+    , entIso639_2    = ["rus"]
+    , entIso639_3    = Just "rus"
+    , entNativeNames = ["Русский язык"]
+    , entEnglishName = Just "Russian"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β) ⇒ α → β
-struct = pos 
-       $ fix 
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β) ⇒ α → β
+struct = pos
+       $ fix
        $ findRule (   0, lit               )
                 [ (  11, add 10 L          )
                 , (  20, mul 10 R L        )
@@ -70,9 +81,12 @@
                 ]
                   (dec 6 - 1)
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 6 - 1 in (negate x, x)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprAdd   = Just (⊞)
                , reprMul   = Just (⊡)
                , reprNeg   = Just $ \_ _ → "минус "
diff --git a/src/Text/Numeral/Language/SCO.hs b/src/Text/Numeral/Language/SCO.hs
--- a/src/Text/Numeral/Language/SCO.hs
+++ b/src/Text/Numeral/Language/SCO.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        -
@@ -17,8 +16,14 @@
 -}
 
 module Text.Numeral.Language.SCO
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -28,28 +33,36 @@
 
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
 import "base" Prelude       ( Integral )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 -------------------------------------------------------------------------------
 -- SCO
 -------------------------------------------------------------------------------
 
-{-
-Sources:
-  http://www.sf.airnet.ne.jp/~ts/language/number/scots.html
--}
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_2    = ["sco"]
+    , entIso639_3    = Just "sco"
+    , entNativeNames = ["Scots"]
+    , entEnglishName = Just "Scots"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ α → β
 struct = checkPos
        $ fix
        $ findRule (  1, lit       )
@@ -59,9 +72,12 @@
                 ]
                    100
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (1, 100)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprAdd   = Just (⊞)
                , reprMul   = Just $ \_ _ _ → ""
                }
diff --git a/src/Text/Numeral/Language/SV.hs b/src/Text/Numeral/Language/SV.hs
--- a/src/Text/Numeral/Language/SV.hs
+++ b/src/Text/Numeral/Language/SV.hs
@@ -1,8 +1,8 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        sv
@@ -17,8 +17,15 @@
 -}
 
 module Text.Numeral.Language.SV
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+    , ordinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -26,63 +33,124 @@
 -- Imports
 -------------------------------------------------------------------------------
 
+import "base" Data.Bool     ( otherwise )
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
-import "base" Prelude       ( Integral, (-), Integer )
+import "base" Prelude       ( Num, Integral, (-), div, negate, even )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.BigNum      as BN
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum as BN
+import qualified "this" Text.Numeral.Exp    as E
+import qualified "this" Text.Numeral.Grammar as G
+import           "this" Text.Numeral.Misc ( dec, intLog )
+import "this" Text.Numeral.Entry
+import "this" Text.Numeral.Render.Utils ( addCtx, mulCtx, outsideCtx )
+import "text" Data.Text ( Text )
 
 
 -------------------------------------------------------------------------------
 -- SV
 -------------------------------------------------------------------------------
 
-cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "sv"
+    , entIso639_2    = ["swe"]
+    , entIso639_3    = Just "swe"
+    , entNativeNames = ["svenska"]
+    , entEnglishName = Just "Swedish"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    , entOrdinal     = Just Conversion
+                       { toNumeral   = ordinal
+                       , toStructure = struct
+                       }
+    }
 
-struct ∷ ( Integral α, C.Scale α
-         , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β
+cardinal ∷ (G.Common i, G.Neuter i, Integral α, E.Scale α)
+         ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+ordinal ∷ (G.Common i, G.Neuter i, Integral α, E.Scale α)
+        ⇒ i → α → Maybe Text
+ordinal inf = ordinalRepr inf ∘ struct
+
+struct ∷ ( Integral α, E.Scale α
+         , E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β, E.Scale β
+         , E.Inflection β, G.Common (E.Inf β)
          )
        ⇒ α → β
-struct = pos $ fix $ rule `combine` pelletierScale R L BN.rule
+struct = pos $ fix $ rule `combine` pelletierScale1_sv
     where
       rule = findRule (   0, lit       )
                     [ (  13, add 10 L  )
                     , (  20, lit       )
                     , (  21, add 20 R  )
                     , (  30, mul 10 R L)
-                    , ( 100, step  100   10 R L)
-                    , (1000, step 1000 1000 R L)
+                    , ( 100, step1 100   10 R L)
+                    , (1000, step1 1000 1000 R L)
                     ]
                       (dec 6 - 1)
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+-- | Like 'pelletierScale1' with the difference that all scale
+-- elements are of the common gender.
+pelletierScale1_sv ∷ ( Integral α, E.Scale α
+                     , E.Unknown β, E.Lit β, E.Add β, E.Mul β, E.Scale β
+                     , E.Inflection β, G.Common (E.Inf β)
+                     )
+                   ⇒ Rule α β
+pelletierScale1_sv =
+    conditional (\n → even $ intLog n `div` 3)
+                (mulScale1_sv 6 0 R L BN.rule)
+                (mulScale1_sv 6 3 R L BN.rule)
+  where
+    mulScale1_sv = mulScale_ $ \f m s _ → commonMul (f m) s
+    commonMul m s = E.inflection (G.common) $ E.mul m s
+
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 60000 - 1 in (negate x, x)
+
+cardinalRepr ∷ (G.Common i, G.Neuter i) ⇒ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
-               , reprScale = pelletierRepr
-               , reprAdd   = Just $ \_ _ _ → ""
-               , reprMul   = Just $ \_ _ _ → ""
+               { reprValue = \ctx n → M.lookup n (syms ctx)
+               , reprScale = BN.pelletierRepr
+                               (BN.quantityName "iljon"  "iljoner")
+                               (BN.quantityName "iljard" "iljarder")
+                               bigNumSyms
+               , reprAdd   = Just (⊞)
+               , reprMul   = Just (⊡)
                , reprNeg   = Just $ \_ _   → "minus "
                }
     where
-      syms =
+      (Inflection _ _ ⊞ _) _ = " "
+      (_ ⊞ _) _ = ""
+
+      (_ ⊡ Lit  100) CtxEmpty = " "
+      (_ ⊡ Lit 1000) CtxEmpty = " "
+      (_ ⊡ Scale{})  _ = " "
+      (_ ⊡ _) _ = ""
+
+      syms ctx =
           M.fromList
-          [ (0,  const "noll")
-          , (1,  const "ett")
-          , (2,  const "två")
-          , (3,  ten   "tre"  "tret" "tret")
-          , (4,  ten   "fyra" "fjor" "fyr")
-          , (5,  const "fem")
-          , (6,  const "sex")
-          , (7,  ten   "sju"  "sjut" "sjut")
-          , (8,  ten   "åtta" "ar"   "åt")
-          , (9,  ten   "nio"  "nit"  "nit")
+          [ (0, const "noll")
+          , (1, \c → case c of
+                       CtxMul _ (Lit 1000) CtxEmpty → "ett"
+                       CtxMul _ (Lit 1000) _ → "et"
+                       _ | G.isCommon ctx → "en"
+                         | G.isNeuter ctx → "ett"
+                         | otherwise      → "?"
+            )
+          , (2, const "två")
+          , (3, addCtx 10 "tret" $ mulCtx 10 "tret" $ const "tre")
+          , (4, addCtx 10 "fjor" $ mulCtx 10 "fyr"  $ const "fyra")
+          , (5, const "fem")
+          , (6, const "sex")
+          , (7, addCtx 10 "sjut" $ mulCtx 10 "sjut" $ const "sju")
+          , (8, addCtx 10 "ar"   $ mulCtx 10 "åt"   $ const "åtta")
+          , (9, addCtx 10 "nit"  $ mulCtx 10 "nit"  $ const "nio")
           , (10, \c → case c of
                         CtxAdd {} → "ton"
                         _         → "tio"
@@ -94,18 +162,62 @@
           , (1000, const "tusen")
           ]
 
-      ten n a m = \c → case c of
-                         CtxAdd _ (Lit 10) _ → a
-                         CtxMul _ (Lit 10) _ → m
-                         _                   → n
+ordinalRepr ∷ (G.Common i, G.Neuter i) ⇒ i → Exp i → Maybe Text
+ordinalRepr = render defaultRepr
+              { reprValue = \ctx n → M.lookup n (syms ctx)
+              , reprScale = BN.pelletierRepr
+                               (BN.ordQuantityName "iljon"  "iljonte" "iljoner"  "iljonte")
+                               (BN.ordQuantityName "iljard" "iljarte" "iljarder" "iljarte")
+                               bigNumSyms
+              , reprAdd   = Just (⊞)
+              , reprMul   = Just (⊡)
+              , reprNeg   = Just $ \_ _   → "minus "
+              }
+    where
+      (Inflection _ _ ⊞ _) _ = " "
+      (_ ⊞ _) _ = ""
 
-pelletierRepr ∷ (IsString s, Monoid s)
-              ⇒ Integer → Integer → Exp → Ctx Exp → Maybe s
-pelletierRepr =
-    BN.pelletierRepr
-      "iljon"  "iljon"
-      "iljard" "iljard"
-      [ (4, BN.forms "kvadr" "kvattuor" "kvattuor" "kvadra"  "kvadri")
-      , (5, BN.forms "kvint" "kvin"     "kvinkva"  "kvinkva" "kvin")
-      , (8, BN.forms "okt"   "okto"     "okto"     "okto"    "oktin")
-      ]
+      (_ ⊡ Lit  100) CtxEmpty = " "
+      (_ ⊡ Lit 1000) CtxEmpty = " "
+      (_ ⊡ Scale{})  _ = " "
+      (_ ⊡ _) _ = ""
+
+      syms ctx =
+          M.fromList
+          [ (0, outsideCtx R "nollte" $ const "noll")
+          , (1, outsideCtx R "första"
+                $ \c → case c of
+                         CtxMul _ (Lit 1000) CtxEmpty → "ett"
+                         CtxMul _ (Lit 1000) _ → "et"
+                         _ | G.isCommon ctx → "en"
+                           | G.isNeuter ctx → "ett"
+                           | otherwise      → "?"
+            )
+          , (2, outsideCtx R "andra"   $ const "två")
+          , (3, outsideCtx R "tredje"  $ addCtx 10 "tret" $ mulCtx 10 "tret" $ const "tre")
+          , (4, outsideCtx R "fjärde"  $ addCtx 10 "fjor" $ mulCtx 10 "fyr"  $ const "fyra")
+          , (5, outsideCtx R "femte"   $ const "fem")
+          , (6, outsideCtx R "sjätte"  $ const "sex")
+          , (7, outsideCtx R "sjunde"  $ addCtx 10 "sjut" $ mulCtx 10 "sjut" $ const "sju")
+          , (8, outsideCtx R "åttonde" $ addCtx 10 "ar"   $ mulCtx 10 "åt"   $ const "åtta")
+          , (9, outsideCtx R "nionde"  $ addCtx 10 "nit"  $ mulCtx 10 "nit"  $ const "nio")
+          , (10, \c → case c of
+                        CtxAdd {}
+                          | isOutside R c → "tonde"
+                          | otherwise     → "ton"
+                        _ | isOutside R c → "tionde"
+                          | otherwise     → "tio"
+            )
+          , (11, outsideCtx R "elfte"    $ const "elva")
+          , (12, outsideCtx R "tolfte"   $ const "tolv")
+          , (20, outsideCtx R "tjugonde" $ const "tjugo")
+          , (100, outsideCtx R "hundrade" $ const "hundra")
+          , (1000, outsideCtx R "tusende" $ const "tusen")
+          ]
+
+bigNumSyms ∷ (Num α) ⇒ [(α, Ctx (Exp i) → Text)]
+bigNumSyms =
+    [ (4, BN.forms "kvadr" "kvattuor" "kvattuor" "kvadra"  "kvadri")
+    , (5, BN.forms "kvint" "kvin"     "kvinkva"  "kvinkva" "kvin")
+    , (8, BN.forms "okt"   "okto"     "okto"     "okto"    "oktin")
+    ]
diff --git a/src/Text/Numeral/Language/TR.hs b/src/Text/Numeral/Language/TR.hs
--- a/src/Text/Numeral/Language/TR.hs
+++ b/src/Text/Numeral/Language/TR.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        tr
@@ -17,8 +16,14 @@
 -}
 
 module Text.Numeral.Language.TR
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -29,43 +34,46 @@
 import "base" Data.Bool           ( otherwise )
 import "base" Data.Function       ( ($), const, fix )
 import "base" Data.Maybe          ( Maybe(Just) )
-import "base" Data.Monoid         ( Monoid )
-import "base" Data.String         ( IsString )
-import "base" Prelude             ( Integral, (-), divMod, Integer )
+import "base" Prelude             ( Integral, (-), divMod, negate )
 import "base-unicode-symbols" Data.Eq.Unicode       ( (≡) )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import "base-unicode-symbols" Data.List.Unicode     ( (∉) )
-import "base-unicode-symbols" Prelude.Unicode       ( (⋅) )
+import "base-unicode-symbols" Prelude.Unicode       ( ℤ, (⋅) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
-import qualified "numerals-base" Text.Numeral.BigNum as BN ( rule, scaleRepr, forms )
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.BigNum as BN ( rule, scaleRepr, forms )
+import qualified "this" Text.Numeral.Exp    as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- TR
 --------------------------------------------------------------------------------
 
-{-
-
-Sources:
-  http://www.languagesandnumbers.com/how-to-count-in-turkish/en/tur/
-  http://www.sf.airnet.ne.jp/~ts/language/number/turkish.html
-  http://www.turkishlanguage.co.uk/seasons.htm#article_15
-  http://www.turkeytravelplanner.com/details/LanguageGuide/100words_lessons/100Words_10.html
-  http://en.wikibooks.org/wiki/Turkish/Numbers
-  http://tr.wikipedia.org/wiki/B%C3%BCy%C3%BCk_say%C4%B1lar%C4%B1n_adlar%C4%B1
--}
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "tr"
+    , entIso639_2    = ["tur"]
+    , entIso639_3    = Just "tur"
+    , entNativeNames = ["Türkçe"]
+    , entEnglishName = Just "Turkish"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+cardinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
 
-struct ∷ (Integral α, C.Scale α, C.Unknown β, C.Lit β, C.Add β, C.Mul β, C.Scale β)
+struct ∷ (Integral α, E.Scale α, E.Unknown β, E.Lit β, E.Add β, E.Mul β, E.Scale β)
        ⇒ α → β
 struct = checkPos $ fix $ rule `combine` shortScale1 R L BN.rule
 
-rule ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ Rule α β
+rule ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ Rule α β
 rule = findRule (   0, lit               )
               [ (  11, addToTens         )
               , ( 100, step  100   10 R L)
@@ -73,16 +81,19 @@
               ]
                 (dec 6 - 1)
 
-addToTens ∷ (Integral α, C.Lit β, C.Add β) ⇒ Rule α β
+addToTens ∷ (Integral α, E.Lit β, E.Add β) ⇒ Rule α β
 addToTens f n = let (m, r) = n `divMod` 10
                     tens   = m ⋅ 10
                 in if r ≡ 0
                    then lit f tens
-                   else f tens `C.add` f r
+                   else f tens `E.add` f r
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 60000 - 1 in (negate x, x)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprScale = scaleRepr
                , reprAdd   = Just (⊞)
                , reprMul   = Just $ \_ _ _ → " "
@@ -96,10 +107,7 @@
           [ (0, const "sıfır")
           , (1, const "bir")
           , (2, const "iki")
-          , (3, \c → case c of
-                       CtxEmpty → "üç"
-                       _        → "uç"
-            )
+          , (3, const "üç")
           , (4, const "dört")
           , (5, const "beş")
           , (6, const "altı")
@@ -119,10 +127,9 @@
           , (1000, const "bin")
           ]
 
-scaleRepr ∷ (IsString s, Monoid s)
-              ⇒ Integer → Integer → Exp → Ctx Exp → Maybe s
+scaleRepr ∷ i → ℤ → ℤ → Exp i → Ctx (Exp i) → Maybe Text
 scaleRepr = BN.scaleRepr
-              "ilyon" "ilyon"
+              (\_ _ → "ilyon")
               [ (1, BN.forms "m"     "an"     "an"     ""       "")
               , (2, BN.forms "b"     "do"     "do"     "vi"     "du")
               , (3, \c → case c of
diff --git a/src/Text/Numeral/Language/WO.hs b/src/Text/Numeral/Language/WO.hs
--- a/src/Text/Numeral/Language/WO.hs
+++ b/src/Text/Numeral/Language/WO.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        wo
@@ -17,42 +16,57 @@
 -}
 
 module Text.Numeral.Language.WO
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
+
 --------------------------------------------------------------------------------
 -- Imports
 --------------------------------------------------------------------------------
 
-{-
-Sources:
-  http://en.wikipedia.org/wiki/Wolof_language#Numerals
-  http://www.sf.airnet.ne.jp/~ts/language/number/wolof.html
--}
-
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
 import "base" Prelude       ( Integral )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import "base-unicode-symbols" Data.Monoid.Unicode   ( (⊕) )
 import "base-unicode-symbols" Data.Ord.Unicode      ( (≥) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- WO
 --------------------------------------------------------------------------------
 
-cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "wo"
+    , entIso639_2    = ["wol"]
+    , entIso639_3    = Just "wol"
+    , entNativeNames = ["Wolof"]
+    , entEnglishName = Just "Wolof"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β
+cardinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ α → β
 struct = checkPos
        $ fix
        $ findRule (  0, lit        )
@@ -66,9 +80,12 @@
                 ]
                   (dec 6)
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (0, dec 6)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprAdd   = Just (⊞)
                , reprMul   = Just (⊡)
                }
diff --git a/src/Text/Numeral/Language/YOR.hs b/src/Text/Numeral/Language/YOR.hs
--- a/src/Text/Numeral/Language/YOR.hs
+++ b/src/Text/Numeral/Language/YOR.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        yo
@@ -17,8 +16,14 @@
 -}
 
 module Text.Numeral.Language.YOR
-    ( cardinal
+    ( -- * Language entry
+      entry
+      -- * Conversions
+    , cardinal
+      -- * Structure
     , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -29,15 +34,16 @@
 import "base" Data.Bool     ( otherwise )
 import "base" Data.Function ( ($), const, fix )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
-import "base" Data.String   ( IsString )
 import "base" Prelude       ( Integral )
 import "base-unicode-symbols" Data.Eq.Unicode       ( (≡) )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import "base-unicode-symbols" Data.Monoid.Unicode   ( (⊕) )
 import qualified "containers" Data.Map as M ( fromList, lookup )
-import           "numerals-base" Text.Numeral
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
@@ -57,10 +63,23 @@
 525 = (200*3) - (20*4) + 5
 -}
 
-cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-cardinal = cardinalRepr ∘ struct
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "yo"
+    , entIso639_2    = ["yor"]
+    , entIso639_3    = Just "yor"
+    , entNativeNames = ["èdè Yorùbá"]
+    , entEnglishName = Just "Yoruba"
+    , entCardinal    = Just Conversion
+                       { toNumeral   = cardinal
+                       , toStructure = struct
+                       }
+    }
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Sub β, C.Mul β) ⇒ α → β
+cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+cardinal inf = cardinalRepr inf ∘ struct
+
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Sub β, E.Mul β) ⇒ α → β
 struct = checkPos
        $ fix
        $ conditional (≡ -5) lit
@@ -96,9 +115,12 @@
                 ]
                    1000
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = (1, 1000)
+
+cardinalRepr ∷ i → Exp i → Maybe Text
 cardinalRepr = render defaultRepr
-               { reprValue = \n → M.lookup n syms
+               { reprValue = \_ n → M.lookup n syms
                , reprAdd   = Just (⊞)
                , reprMul   = Just (⊡)
                , reprSub   = Just $ \_ _ _ → "dil"
diff --git a/src/Text/Numeral/Language/ZH.hs b/src/Text/Numeral/Language/ZH.hs
--- a/src/Text/Numeral/Language/ZH.hs
+++ b/src/Text/Numeral/Language/ZH.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude
-           , OverloadedStrings
-           , PackageImports
-           , UnicodeSyntax
-  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PackageImports    #-}
+{-# LANGUAGE UnicodeSyntax     #-}
 
 {-|
 [@ISO639-1@]        zh
@@ -19,12 +18,22 @@
 -}
 
 module Text.Numeral.Language.ZH
-    ( struct
+    ( -- * Language entries
+      trad_entry
+    , simpl_entry
+    , finance_trad_entry
+    , finance_simpl_entry
+    , pinyin_entry
+      -- * Conversions
     , trad_cardinal
     , simpl_cardinal
     , finance_trad_cardinal
     , finance_simpl_cardinal
     , pinyin_cardinal
+      -- * Structure
+    , struct
+      -- * Bounds
+    , bounds
     ) where
 
 
@@ -35,52 +44,57 @@
 import "base" Data.Bool     ( otherwise )
 import "base" Data.Function ( id, const, fix, flip, ($) )
 import "base" Data.Maybe    ( Maybe(Just) )
-import "base" Data.Monoid   ( Monoid )
 import "base" Data.Ord      ( (<) )
-import "base" Data.String   ( IsString )
-import "base" Prelude       ( Num, Integral, fromIntegral, (-), div, divMod )
+import "base" Prelude       ( Num, Integral, fromIntegral, (-), div, divMod, negate )
 import "base-unicode-symbols" Data.Eq.Unicode       ( (≡) )
 import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
 import "base-unicode-symbols" Data.Monoid.Unicode   ( (⊕) )
 import "base-unicode-symbols" Data.Ord.Unicode      ( (≥) )
 import qualified "containers" Data.Map as M ( Map, fromList, lookup )
 import "containers-unicode-symbols" Data.Map.Unicode ( (∪) )
-import           "numerals-base" Text.Numeral
-import           "numerals-base" Text.Numeral.Misc ( dec )
-import qualified "numerals-base" Text.Numeral.Exp.Classes as C
+import           "this" Text.Numeral
+import qualified "this" Text.Numeral.Exp as E
+import           "this" Text.Numeral.Grammar ( Inflection )
+import           "this" Text.Numeral.Misc ( dec )
+import "this" Text.Numeral.Entry
+import "text" Data.Text ( Text )
 
 
 --------------------------------------------------------------------------------
 -- ZH
 --------------------------------------------------------------------------------
 
-{-
-Sources:
-  http://www.sf.airnet.ne.jp/~ts/language/number/mandarin.html
--}
+entry ∷ Entry
+entry = emptyEntry
+    { entIso639_1    = Just "zh"
+    , entIso639_2    = ["chi", "zho"]
+    , entIso639_3    = Just "cmn"
+    , entNativeNames = ["官話"]
+    , entEnglishName = Just "Chinese"
+    }
 
 flipIfR ∷ Side → (α → α → α) → (α → α → α)
 flipIfR L = id
 flipIfR R = flip
 
-add0 ∷ (Integral α, C.Lit β, C.Add β) ⇒ α → Rule α β
-add0 val f n | n < val `div` 10 = C.lit 0 `C.add` f n
+add0 ∷ (Integral α, E.Lit β, E.Add β) ⇒ α → Rule α β
+add0 val f n | n < val `div` 10 = E.lit 0 `E.add` f n
              | otherwise        = f n
 
-mulX ∷ (Integral α, C.Lit β, C.Add β, C.Mul β)
+mulX ∷ (Integral α, E.Lit β, E.Add β, E.Mul β)
      ⇒ α → Side → Side → Rule α β
 mulX val aSide mSide =
     \f n → let (m, a) = n `divMod` val
                mval = if m ≡ 1
-                      then C.lit 1 ⊡ C.lit (fromIntegral val)
-                      else f m ⊡ C.lit (fromIntegral val)
+                      then E.lit 1 ⊡ E.lit (fromIntegral val)
+                      else f m ⊡ E.lit (fromIntegral val)
            in if a ≡ 0
               then mval
-              else (flipIfR aSide C.add) (add0 val f a) mval
+              else (flipIfR aSide E.add) (add0 val f a) mval
   where
-     (⊡) = flipIfR mSide C.mul
+     (⊡) = flipIfR mSide E.mul
 
-struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β) ⇒ α → β
+struct ∷ (Integral α, E.Unknown β, E.Lit β, E.Neg β, E.Add β, E.Mul β) ⇒ α → β
 struct = pos
        $ fix
        $ findRule (0, lit)
@@ -92,9 +106,12 @@
     where
       stepX = mkStep lit1 addX mulX
 
-      addX val _ = \f n → C.add (f val) (add0 val f $ n - val)
+      addX val _ = \f n → E.add (f val) (add0 val f $ n - val)
 
-cardinalRepr ∷ (Monoid s, IsString s) ⇒ Repr s
+bounds ∷ (Integral α) ⇒ (α, α)
+bounds = let x = dec 48 - 1 in (negate x, x)
+
+cardinalRepr ∷ Repr i
 cardinalRepr = defaultRepr
                { reprAdd = Just $ \_ _ _ → ""
                , reprMul = Just $ \_ _ _ → ""
@@ -105,17 +122,26 @@
 -- Traditional Characters
 --------------------------------------------------------------------------------
 
-trad_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-trad_cardinal = trad_cardinalRepr ∘ struct
+trad_entry ∷ Entry
+trad_entry = entry
+    { entVariant  = Just "traditional"
+    , entCardinal = Just Conversion
+                    { toNumeral   = trad_cardinal
+                    , toStructure = struct
+                    }
+    }
 
-trad_cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+trad_cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+trad_cardinal inf = trad_cardinalRepr inf ∘ struct
+
+trad_cardinalRepr ∷ i → Exp i → Maybe Text
 trad_cardinalRepr =
     render cardinalRepr
-    { reprValue = \n → M.lookup n trad_syms
-    , reprNeg = Just $ \_ _ → "負"
-    }
+           { reprValue = \_ n → M.lookup n trad_syms
+           , reprNeg = Just $ \_ _ → "負"
+           }
 
-trad_syms ∷ (Integral α, IsString s) ⇒ M.Map α (Ctx Exp → s)
+trad_syms ∷ (Integral α) ⇒ M.Map α (Ctx (Exp i) → Text)
 trad_syms =
     M.fromList
     [ (0, \c → case c of
@@ -155,17 +181,26 @@
 -- Simplified Characters
 --------------------------------------------------------------------------------
 
-simpl_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-simpl_cardinal = simpl_cardinalRepr ∘ struct
+simpl_entry ∷ Entry
+simpl_entry = entry
+    { entVariant  = Just "simplified"
+    , entCardinal = Just Conversion
+                    { toNumeral   = simpl_cardinal
+                    , toStructure = struct
+                    }
+    }
 
-simpl_cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+simpl_cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+simpl_cardinal inf = simpl_cardinalRepr inf ∘ struct
+
+simpl_cardinalRepr ∷ i → Exp i → Maybe Text
 simpl_cardinalRepr =
     render cardinalRepr
-            { reprValue = \n → M.lookup n (simpl_syms ∪ trad_syms)
-            , reprNeg = Just $ \_ _ → "负"
-            }
+           { reprValue = \_ n → M.lookup n (simpl_syms ∪ trad_syms)
+           , reprNeg = Just $ \_ _ → "负"
+           }
 
-simpl_syms ∷ (Integral α, IsString s) ⇒ M.Map α (Ctx Exp → s)
+simpl_syms ∷ (Integral α) ⇒ M.Map α (Ctx (Exp i) → Text)
 simpl_syms =
     M.fromList
     [ (2, \c → case c of
@@ -181,17 +216,26 @@
 -- Financial Characters (Traditional)
 --------------------------------------------------------------------------------
 
-finance_trad_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-finance_trad_cardinal = finance_trad_cardinalRepr ∘ struct
+finance_trad_entry ∷ Entry
+finance_trad_entry = entry
+    { entVariant  = Just "finance traditional"
+    , entCardinal = Just Conversion
+                    { toNumeral   = finance_trad_cardinal
+                    , toStructure = struct
+                    }
+    }
 
-finance_trad_cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+finance_trad_cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+finance_trad_cardinal inf = finance_trad_cardinalRepr inf ∘ struct
+
+finance_trad_cardinalRepr ∷ i → Exp i → Maybe Text
 finance_trad_cardinalRepr =
     render cardinalRepr
-    { reprValue = \n → M.lookup n (finance_trad_syms ∪ trad_syms)
-    , reprNeg = Just $ \_ _ → "負"
-    }
+           { reprValue = \_ n → M.lookup n (finance_trad_syms ∪ trad_syms)
+           , reprNeg = Just $ \_ _ → "負"
+           }
 
-finance_trad_syms ∷ (Integral α, IsString s) ⇒ M.Map α (Ctx Exp → s)
+finance_trad_syms ∷ (Integral α) ⇒ M.Map α (Ctx (Exp i) → Text)
 finance_trad_syms =
     M.fromList
     [ (0, const "零")
@@ -216,20 +260,29 @@
 -- Financial Characters (Simplified)
 --------------------------------------------------------------------------------
 
-finance_simpl_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-finance_simpl_cardinal = finance_simpl_cardinalRepr ∘ struct
+finance_simpl_entry ∷ Entry
+finance_simpl_entry = entry
+    { entVariant  = Just "finance simplified"
+    , entCardinal = Just Conversion
+                    { toNumeral   = finance_simpl_cardinal
+                    , toStructure = struct
+                    }
+    }
 
-finance_simpl_cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+finance_simpl_cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+finance_simpl_cardinal inf = finance_simpl_cardinalRepr inf ∘ struct
+
+finance_simpl_cardinalRepr ∷ i → Exp i → Maybe Text
 finance_simpl_cardinalRepr =
     render cardinalRepr
-    { reprValue = \n → M.lookup n ( finance_simpl_syms
-                                  ∪ finance_trad_syms
-                                  ∪ trad_syms
-                                  )
-    , reprNeg = Just $ \_ _ → "负"
-    }
+           { reprValue = \_ n → M.lookup n ( finance_simpl_syms
+                                           ∪ finance_trad_syms
+                                           ∪ trad_syms
+                                           )
+           , reprNeg = Just $ \_ _ → "负"
+           }
   where
-    finance_simpl_syms ∷ (Integral α, IsString s) ⇒ M.Map α (Ctx Exp → s)
+    finance_simpl_syms ∷ (Integral α) ⇒ M.Map α (Ctx (Exp i) → Text)
     finance_simpl_syms =
         M.fromList
         [ (2, const "贰")
@@ -243,21 +296,30 @@
 -- Pinyin
 --------------------------------------------------------------------------------
 
-pinyin_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s
-pinyin_cardinal = pinyin_cardinalRepr ∘ struct
+pinyin_entry ∷ Entry
+pinyin_entry = entry
+    { entVariant  = Just "pinyin"
+    , entCardinal = Just Conversion
+                    { toNumeral   = pinyin_cardinal
+                    , toStructure = struct
+                    }
+    }
 
-pinyin_cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s
+pinyin_cardinal ∷ (Inflection i, Integral α) ⇒ i → α → Maybe Text
+pinyin_cardinal inf = pinyin_cardinalRepr inf ∘ struct
+
+pinyin_cardinalRepr ∷ i → Exp i → Maybe Text
 pinyin_cardinalRepr =
     render cardinalRepr
-            { reprValue = \n → M.lookup n pinyin_syms
-            , reprNeg = Just $ \_ _ → "fù"
-            , reprAdd = Just (⊞)
-            }
+           { reprValue = \_ n → M.lookup n pinyin_syms
+           , reprNeg = Just $ \_ _ → "fù"
+           , reprAdd = Just (⊞)
+           }
   where
     (Lit 10 ⊞ _) _ = ""
     (_      ⊞ _) _ = " "
 
-    pinyin_syms ∷ (Integral α, IsString s) ⇒ M.Map α (Ctx Exp → s)
+    pinyin_syms ∷ (Integral α) ⇒ M.Map α (Ctx (Exp i) → Text)
     pinyin_syms =
         M.fromList
         [ (0, const "líng")
diff --git a/src/Text/Numeral/Misc.hs b/src/Text/Numeral/Misc.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Misc.hs
@@ -0,0 +1,49 @@
+{-# LANGUAGE CPP
+           , MagicHash
+           , NoImplicitPrelude
+           , PackageImports
+           , UnicodeSyntax
+  #-}
+
+module Text.Numeral.Misc where
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base" Prelude ( Integral, (^) )
+#if __GLASGOW_HASKELL__ >= 702
+import "base" Data.Function ( ($) )
+import "base" GHC.Exts      ( Int(I#) )
+import "base" Prelude       ( fromIntegral, toInteger )
+import "integer-gmp" GHC.Integer.Logarithms ( integerLogBase# )
+#else
+import "base" Data.Bool ( otherwise )
+import "base" Data.Ord  ( (<) )
+import "base" Prelude   ( div, (+), ($!), error )
+#endif
+
+--------------------------------------------------------------------------------
+-- Misc
+--------------------------------------------------------------------------------
+
+-- ^ Raise 10 to some power.
+dec ∷ (Integral α) ⇒ α → α
+dec = (10 ^)
+
+-- ^ The (base 10) logarithm of an integral value. Note that the
+-- result must be able to fit in an ordinary Int value. This means the
+-- maximum input value is 10 ^ (maxBound ∷ Int).
+intLog ∷ (Integral α) ⇒ α → α
+-- GHC >= 7.2.x
+#if __GLASGOW_HASKELL__ >= 702
+intLog x = fromIntegral $ I# (integerLogBase# 10 (toInteger x))
+#else
+intLog x | x < 0 = error "intLog: undefined for negative numbers"
+         | otherwise = go x 0
+    where
+      go n acc = case n `div` 10 of
+                   0 → acc
+                   1 → acc + 1
+                   q → go q $! acc + 1
+#endif
diff --git a/src/Text/Numeral/Render.hs b/src/Text/Numeral/Render.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Render.hs
@@ -0,0 +1,230 @@
+{-# LANGUAGE NoImplicitPrelude
+           , UnicodeSyntax
+           , PackageImports
+           , RecordWildCards
+  #-}
+
+module Text.Numeral.Render
+    ( -- * Rendering numerals
+      render
+      -- * Representation of numerals
+    , Repr(..)
+    , ScaleRepr
+    , defaultRepr
+      -- * Context of expressions
+    , Ctx(..)
+    , posIndex
+    , isOutside
+    )
+    where
+
+
+-------------------------------------------------------------------------------
+-- Imports
+-------------------------------------------------------------------------------
+
+import "base" Data.Bool     ( Bool(False, True), otherwise )
+import "base" Data.Eq       ( Eq )
+import "base" Data.Function ( ($) )
+import "base" Data.Functor  ( (<$>) )
+import "base" Data.Maybe    ( Maybe(Nothing, Just) )
+import "base" Prelude       ( (+) )
+import "base" Text.Show     ( Show )
+import "base-unicode-symbols" Data.Eq.Unicode     ( (≡) )
+import "base-unicode-symbols" Data.Monoid.Unicode ( (⊕) )
+import "base-unicode-symbols" Prelude.Unicode     ( ℤ )
+import "text"                 Data.Text ( Text )
+import "this"                 Text.Numeral.Exp.Reified ( Exp(..), Side(L, R) )
+
+
+-------------------------------------------------------------------------------
+-- Rendering numerals
+-------------------------------------------------------------------------------
+
+-- | Renders an expression to a 'Text' value according to a certain
+-- representation and inflection.
+render ∷ Repr i -- ^ Representation.
+       → i      -- ^ Initial inflection.
+       → Exp i  -- ^ The expression to render.
+       → Maybe Text
+render (Repr {..}) = go CtxEmpty
+    where
+      go _   _   Unknown = reprUnknown
+      go ctx inf (Lit n) = ($ ctx) <$> reprValue inf n
+      go ctx inf (Neg x) = do x' ← go (CtxNeg ctx) inf x
+                              rn ← reprNeg
+                              rnc ← reprNegCombine
+                              Just $ rnc (rn x ctx) x' x
+      go ctx inf (Add x y) = do x' ← go (CtxAdd L y ctx) inf x
+                                y' ← go (CtxAdd R x ctx) inf y
+                                ra ← reprAdd
+                                rac ← reprAddCombine
+                                Just $ rac (ra x y ctx) x' x y' y
+      go ctx inf (Mul x y) = do x' ← go (CtxMul L y ctx) inf x
+                                y' ← go (CtxMul R x ctx) inf y
+                                rm ← reprMul
+                                rmc ← reprMulCombine
+                                Just $ rmc (rm x y ctx) x' x y' y
+      go ctx inf (Sub x y) = do x' ← go (CtxSub L y ctx) inf x
+                                y' ← go (CtxSub R x ctx) inf y
+                                rs ← reprSub
+                                rsc ← reprSubCombine
+                                Just $ rsc (rs x y ctx) x' x y' y
+      go ctx inf (Frac x y) = do x' ← go (CtxFrac L y ctx) inf x
+                                 y' ← go (CtxFrac R x ctx) inf y
+                                 rf ← reprFrac
+                                 rfc ← reprFracCombine
+                                 Just $ rfc (rf x y ctx) x' x y' y
+      go ctx inf (Scale b o r) = reprScale inf b o r ctx
+      go ctx inf (Dual   x) = go (CtxDual   ctx) inf x
+      go ctx inf (Plural x) = go (CtxPlural ctx) inf x
+      go ctx inf (Inflection f x) = go ctx (f inf) x
+
+
+--------------------------------------------------------------------------------
+-- Representation of numerals
+--------------------------------------------------------------------------------
+
+-- | A representation for numerals.
+--
+-- A 'Repr' contains all the information on how to render an
+-- 'Exp'ression to a 'Text' value.
+data Repr i =
+    Repr
+    { -- | Representation for unknown values.
+      reprUnknown ∷ Maybe Text
+      -- | Renders a literal value. Not necessarily defined for every
+      -- value.
+    , reprValue ∷ i → ℤ → Maybe (Ctx (Exp i) → Text)
+      -- | Renders a negation. This concerns the negation itself, not
+      -- the thing being negated.
+    , reprNeg ∷ Maybe (Exp i → Ctx (Exp i) → Text)
+      -- | Renders an addition. This concerns the addition itself, not
+      -- the things being added. For example: In \"one hundred and
+      -- eighty\" this function would be responsible for rendering the
+      -- \"and\".
+    , reprAdd ∷ Maybe (Exp i → Exp i → Ctx (Exp i) → Text)
+      -- | Renders a multiplication. This concerns the multiplication
+      -- itself, not the things being multiplied.
+    , reprMul ∷ Maybe (Exp i → Exp i → Ctx (Exp i) → Text)
+      -- | Renders a subtraction. This concerns the subtraction
+      -- itself, not the things being subtracted.
+    , reprSub ∷ Maybe (Exp i → Exp i → Ctx (Exp i) → Text)
+      -- | Renders a fraction. This concerns the fraction itself, not
+      -- the numerator or the denominator.
+    , reprFrac ∷ Maybe (Exp i → Exp i → Ctx (Exp i) → Text)
+      -- | Renders a step in a scale of large values.
+    , reprScale ∷ ScaleRepr i
+      -- | Combines a negation and the thing being negated. For
+      -- example: this would combine \"minus\" and \"three\" into
+      -- \"minus three\".
+    , reprNegCombine ∷ Maybe (Text → Text → Exp i → Text)
+      -- | Combines an addition and the things being added.
+    , reprAddCombine ∷ Maybe (Text → Text → Exp i → Text → Exp i → Text)
+      -- | Combines a multiplication and the things being multiplied.
+    , reprMulCombine ∷ Maybe (Text → Text → Exp i → Text → Exp i → Text)
+      -- | Combines a subtraction and the things being subtracted.
+    , reprSubCombine ∷ Maybe (Text → Text → Exp i → Text → Exp i → Text)
+      -- | Combines a fraction and the numerator and denominator.
+    , reprFracCombine ∷ Maybe (Text → Text → Exp i → Text → Exp i → Text)
+    }
+
+-- | Function that renders the representation of a step in a scale of
+-- large values. The value represented by the step is 10 ^ (rank *
+-- base + offset).
+type ScaleRepr i = i
+                 → ℤ -- ^ Base.
+                 → ℤ -- ^ Offset.
+                 → Exp i -- ^ Rank.
+                 → Ctx (Exp i) -- ^ Rank context.
+                 → Maybe Text
+
+-- | The default representation.
+--
+-- Only the combining functions are defined. The rest are either
+-- 'Nothing' or always produce 'Nothing'.
+defaultRepr ∷ Repr inf
+defaultRepr =
+    Repr { reprUnknown = Nothing
+         , reprValue   = \_ _ → Nothing
+         , reprNeg     = Nothing
+         , reprAdd     = Nothing
+         , reprMul     = Nothing
+         , reprSub     = Nothing
+         , reprFrac    = Nothing
+         , reprScale   = \_ _ _ _ _ → Nothing
+         , reprNegCombine  = Just $ \n x _     → n ⊕ x
+         , reprAddCombine  = Just $ \a x _ y _ → x ⊕ a ⊕ y
+         , reprMulCombine  = Just $ \m x _ y _ → x ⊕ m ⊕ y
+         , reprSubCombine  = Just $ \s x _ y _ → x ⊕ s ⊕ y
+         , reprFracCombine = Just $ \f n _ d _ → n ⊕ f ⊕ d
+         }
+
+
+--------------------------------------------------------------------------------
+-- Context of expressions
+--------------------------------------------------------------------------------
+
+-- | A context in which an 'Exp'ression appears.
+data Ctx α   -- | The empty context. Used for top level expressions.
+           = CtxEmpty
+             -- | Negation context.
+           | CtxNeg (Ctx α)
+             -- | Addition context.
+           | CtxAdd Side α (Ctx α)
+             -- | Multiplication context.
+           | CtxMul Side α (Ctx α)
+             -- | Subtraction context.
+           | CtxSub Side α (Ctx α)
+             -- | Fraction context.
+           | CtxFrac Side α (Ctx α)
+             -- | Scale context.
+           | CtxScale (Ctx α)
+             -- | Dual context.
+           | CtxDual (Ctx α)
+             -- | Plural context.
+           | CtxPlural (Ctx α)
+             deriving (Eq, Show)
+
+
+posIndex ∷ Ctx α → ℤ
+posIndex c = go 0 c
+    where
+      go ∷ ℤ → Ctx α → ℤ
+      go acc CtxEmpty = acc
+      go acc (CtxNeg nc) = go acc nc
+      go acc (CtxAdd  as _ ac) = go (acc + if as ≡ L then -1 else 1) ac
+      go acc (CtxMul  ms _ mc) = go (acc + if ms ≡ L then -1 else 1) mc
+      go acc (CtxSub  ss _ sc) = go (acc + if ss ≡ L then -1 else 1) sc
+      go acc (CtxFrac fs _ fc) = go (acc + if fs ≡ L then -1 else 1) fc
+      go acc (CtxScale  sc) = go acc sc
+      go acc (CtxDual   dc) = go acc dc
+      go acc (CtxPlural pc) = go acc pc
+
+-- | Checks whether a context is completely on the outside of an
+-- expression, either left or right.
+--
+-- Given the following expression:
+--
+-- @
+-- 'Add' ('Lit' 1000) ('Add' ('Mul' ('Lit' 2) ('Lit' 100)) ('Add' ('Lit' 4) ('Mul' ('Lit' 3) ('Lit' 10))))
+-- @
+--
+-- On the left we have @'Lit' 1000@ and on the right @'Lit' 10@.
+isOutside ∷ Side → Ctx α → Bool
+isOutside s c = go c
+    where
+      go ∷ Ctx α → Bool
+      go CtxEmpty = True
+      go (CtxNeg nc) = go nc
+      go (CtxAdd  as _ ac) | as ≡ s    = go ac
+                           | otherwise = False
+      go (CtxMul  ms _ mc) | ms ≡ s    = go mc
+                           | otherwise = False
+      go (CtxSub  ss _ sc) | ss ≡ s    = go sc
+                           | otherwise = False
+      go (CtxFrac fs _ fc) | fs ≡ s    = go fc
+                           | otherwise = False
+      go (CtxScale  sc) = go sc
+      go (CtxDual   dc) = go dc
+      go (CtxPlural pc) = go pc
diff --git a/src/Text/Numeral/Render/Utils.hs b/src/Text/Numeral/Render/Utils.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Render/Utils.hs
@@ -0,0 +1,41 @@
+{-# LANGUAGE NoImplicitPrelude
+           , PackageImports
+           , UnicodeSyntax
+  #-}
+
+module Text.Numeral.Render.Utils
+    ( addCtx
+    , mulCtx
+    , outsideCtx
+    ) where
+
+--------------------------------------------------------------------------------
+-- Imports
+--------------------------------------------------------------------------------
+
+import "base-unicode-symbols" Data.Eq.Unicode ( (≡) )
+import "base-unicode-symbols" Prelude.Unicode ( ℤ )
+import "this" Text.Numeral
+
+
+--------------------------------------------------------------------------------
+-- Utility functions for rendering numerals
+--------------------------------------------------------------------------------
+
+addCtx ∷ ℤ → s → (Ctx (Exp i) → s) → Ctx (Exp i) → s
+addCtx val match other ctx =
+    case ctx of
+      CtxAdd _ (Lit n) _ | val ≡ n → match
+      _ → other ctx
+
+mulCtx ∷ ℤ → s → (Ctx (Exp i) → s) → Ctx (Exp i) → s
+mulCtx val match other ctx =
+    case ctx of
+      CtxMul _ (Lit n) _ | val ≡ n → match
+      _ → other ctx
+
+outsideCtx ∷ Side → s → (Ctx (Exp i) → s) → Ctx (Exp i) → s
+outsideCtx side match other ctx =
+    if isOutside side ctx
+    then match
+    else other ctx
diff --git a/src/Text/Numeral/Rules.hs b/src/Text/Numeral/Rules.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Numeral/Rules.hs
@@ -0,0 +1,373 @@
+{-# LANGUAGE NoImplicitPrelude
+           , PackageImports
+           , UnicodeSyntax
+  #-}
+
+{-|
+
+Rules to convert numbers to an expression language.
+
+-}
+module Text.Numeral.Rules
+  ( -- * The Rule type
+    Rule
+
+    -- * Rule combinators
+  , conditional
+  , combine
+  , mapRule
+  , findRule
+
+    -- * Rules
+  , unknown
+
+  , lit, lit1
+
+  , pos, checkPos
+  , dual, plural
+  , inflection
+
+  , add
+  , mul, mul1
+  , sub
+
+  , mulScale_, mulScale, mulScale1
+  , shortScale,  longScale,  pelletierScale
+  , shortScale1, longScale1, pelletierScale1
+
+  , mkStep, step, step1
+  ) where
+
+
+-------------------------------------------------------------------------------
+-- Imports
+-------------------------------------------------------------------------------
+
+import "base" Data.Bool           ( Bool, otherwise )
+import "base" Data.Function       ( ($), id, const, flip, fix )
+import "base" Data.List           ( foldr )
+import "base" Data.Ord            ( Ord, (<), (>) )
+import "base" Prelude             ( Integral, fromIntegral
+                                  , Num, (-), abs, divMod, div, even
+                                  )
+import "base-unicode-symbols" Data.Eq.Unicode       ( (≡) )
+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )
+import "base-unicode-symbols" Prelude.Unicode       ( (⋅) )
+import "this"                 Text.Numeral.Exp.Reified ( Side(L, R) )
+import "this"                 Text.Numeral.Misc     ( intLog )
+import qualified "this"       Text.Numeral.Exp as E
+import qualified "fingertree" Data.IntervalMap.FingerTree as FT
+    ( Interval(Interval)
+    , IntervalMap, empty, insert
+    , search
+    )
+
+
+--------------------------------------------------------------------------------
+-- The Rule type
+--------------------------------------------------------------------------------
+
+-- | A rule on how to convert a number into an expression
+-- language. Notice how this type is equal to the type of the '$'
+-- operator.
+type Rule α β = (α → β) → (α → β)
+
+
+--------------------------------------------------------------------------------
+-- Rule combinators
+--------------------------------------------------------------------------------
+
+
+-- | The \'if-then-else\' concept for rules. Applies the first rule if
+-- the predicate holds on the input value, otherwise applies the
+-- second rule.
+conditional ∷ (α → Bool) -- ^ Predicate on input value (\"if\").
+            → Rule α β -- ^ Rule to apply when predicate holds (\"then\").
+            → Rule α β -- ^ Rule to apply when predicate does not hold (\"else\").
+            → Rule α β
+conditional p t e = \f n → if p n
+                           then t f n
+                           else e f n
+
+-- | Tries to apply the first rule, if that produces an 'E.unknown'
+-- value it applies the second rule.
+combine ∷ (E.Unknown β)
+        ⇒ Rule α β
+        → Rule α β
+        → Rule α β
+combine r1 r2 = \f n → case r1 f n of
+                         x | E.isUnknown x → r2 f n
+                           | otherwise     → x
+
+-- | Transform a value before it is given to a rule.
+mapRule ∷ (α → α) → Rule α β → Rule α β
+mapRule g r = \f n → r f (g n)
+
+-- | Chooses which rule to apply to an input value based on a interval
+-- list of rules.
+findRule ∷ (Ord α, Num α, E.Unknown β)
+         ⇒ (α, Rule α β)   -- ^ First interval rule.
+         → [(α, Rule α β)] -- ^ Interval rule list.
+         → α               -- ^ Upper bound of the last interval.
+         → Rule α β
+findRule x xs end = \f n → case FT.search n xm of
+                             [] → E.unknown
+                             (_,r):_ → r f n
+    where
+      xm = mkIntervalMap $ mkIntervalList x xs end
+
+
+--------------------------------------------------------------------------------
+-- Rules
+--------------------------------------------------------------------------------
+
+-- | A rule that always fails to convert a value. It constantly
+-- produces the 'E.unknown' value.
+--
+-- >>> (fix unknown) (3 :: Integer) :: Exp
+-- Unknown
+unknown ∷ (E.Unknown β) ⇒ Rule α β
+unknown _ _ = E.unknown
+
+-- | The literal rule. Converts its argument into a 'E.lit'eral
+-- expression.
+--
+-- >>> lit (fix unknown) (3 :: Integer) :: Exp
+-- Lit 3
+--
+-- In this example lit is applied to the nonsense rule \"'fix'
+-- 'unknown'\". Lit ignores that function, which is why we can pass it
+-- anything we want, including itself.
+--
+-- >>> lit (fix undefined) (3 :: Integer) :: Exp
+-- Lit 3
+-- >>> (fix lit) (3 :: Integer) :: Exp
+-- Lit 3
+lit ∷ (Integral α, E.Lit β) ⇒ Rule α β
+lit = const $ E.lit ∘ fromIntegral
+
+-- | A variant on the 'lit' rule which always multiplies its argument
+-- with 1. Useful for languages which have numerals of the form \"one
+-- hundred and three\" as opposed to \"hundred and three\".
+--
+-- >>> lit1 (fix unknown) (3 :: Integer) :: Exp
+-- Mul (Lit 1) (Lit 3)
+lit1 ∷ (Integral α, E.Lit β, E.Mul β) ⇒ Rule α β
+lit1 = const $ \n → E.lit 1 `E.mul` E.lit (fromIntegral n)
+
+-- |
+--
+-- >>> (pos $ lit $ fix unknown) (3 :: Integer) :: Exp
+-- Lit 3
+-- >>> (pos $ lit $ fix unknown) (-3 :: Integer) :: Exp
+-- Neg (Lit 3)
+pos ∷ (Ord α, Num α, E.Lit β, E.Neg β) ⇒ Rule α β
+pos f n | n < 0     = E.neg $ f (abs n)
+        | n > 0     = f n
+        | otherwise = E.lit 0
+
+-- |
+--
+-- >>> (checkPos $ lit $ fix unknown) (3 :: Integer) :: Exp
+-- Lit 3
+-- >>> (checkPos $ lit $ fix unknown) (-3 :: Integer) :: Exp
+-- Unknown
+checkPos ∷ (Ord α, Num α, E.Unknown β, E.Lit β) ⇒ Rule α β
+checkPos f n | n < 0     = E.unknown
+             | n > 0     = f n
+             | otherwise = E.lit 0
+
+-- |
+--
+-- >>> (dual $ lit $ fix unknown) (3 :: Integer) :: Exp
+-- Dual (Lit 3)
+dual ∷ (E.Dual β) ⇒ Rule α β
+dual = (∘) E.dual
+
+-- |
+--
+-- >>> (plural $ lit $ fix unknown) (3 :: Integer) :: Exp
+-- Plural (Lit 3)
+plural ∷ (E.Plural β) ⇒ Rule α β
+plural = (∘) E.plural
+
+-- | Changes the inflection of a subexpression.
+inflection ∷ (E.Inflection β) ⇒ (E.Inf β → E.Inf β) → Rule α β
+inflection changeInf = \f n → E.inflection changeInf $ f n
+
+-- |
+--
+-- >>> (add 10 L $ lit $ fix unknown) (13 :: Integer) :: Exp
+-- Add (Lit 3) (Lit 10)
+add ∷ (Num α, E.Add β) ⇒ α → Side → Rule α β
+add val s = \f n → (flipIfR s E.add) (f $ n - val) (f val)
+
+-- |
+--
+-- >>> (mul 10 R L $ lit $ fix unknown) (42 :: Integer) :: Exp
+-- Add (Mul (Lit 4) (Lit 10)) (Lit 2)
+mul ∷ (Integral α, E.Add β, E.Mul β) ⇒ α → Side → Side → Rule α β
+mul val aSide mSide =
+    \f n → let (m, a) = n `divMod` val
+               mval = (flipIfR mSide E.mul) (f m) (f val)
+           in if a ≡ 0
+              then mval
+              else (flipIfR aSide E.add) (f a) mval
+
+mul1 ∷ (Integral α, E.Lit β, E.Add β, E.Mul β)
+     ⇒ α → Side → Side → Rule α β
+mul1 val aSide mSide =
+    \f n → let (m, a) = n `divMod` val
+               mval = if m ≡ 1
+                      then E.lit 1 ⊡ E.lit (fromIntegral val)
+                      else f m ⊡ E.lit (fromIntegral val)
+           in if a ≡ 0
+              then mval
+              else (flipIfR aSide E.add) (f a) mval
+  where
+     (⊡) = flipIfR mSide E.mul
+
+-- |
+--
+-- >>> (sub 20 $ lit $ fix unknown) (18 :: Integer) :: Exp
+-- Sub (Lit 2) (Lit 20)
+sub ∷ (Integral α, E.Sub β) ⇒ α → Rule α β
+sub val = \f n → E.sub (f $ val - n) (f val)
+
+mkStep ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β)
+       ⇒ Rule α β                     -- ^ lit rule
+       → (α → Side → Rule α β)        -- ^ add rule
+       → (α → Side → Side → Rule α β) -- ^ mul rule
+       → α → α → Side → Side → Rule α β
+mkStep lr ar mr val r aSide mSide
+       f n | n < val   = E.unknown
+           | n ≡ val   = lr                 f n
+           | n < val⋅2 = ar val aSide       f n
+           | n < val⋅r = mr val aSide mSide f n
+           | otherwise = E.unknown
+
+step ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β)
+     ⇒ α → α → Side → Side → Rule α β
+step = mkStep lit add mul
+
+step1 ∷ (Integral α, E.Unknown β, E.Lit β, E.Add β, E.Mul β)
+      ⇒ α → α → Side → Side → Rule α β
+step1 = mkStep lit1 add mul1
+
+mulScale_ ∷ (Integral α, E.Scale α, E.Unknown β, E.Add β, E.Mul β, E.Scale β)
+          ⇒ ( (α → β) -- Parent rule.
+            → α       -- First multiplication value (not converted).
+            → β       -- Second multiplication value (scale step,
+                      -- already converted).
+            → Side    -- Multiplication side.
+            → β
+            )        -- ^ Performs the multiplication.
+          → α        -- ^ Base.
+          → α        -- ^ Offset.
+          → Side     -- ^ Add side.
+          → Side     -- ^ Mul side.
+          → Rule α β -- ^ Big num rule.
+          → Rule α β
+mulScale_ doMul base offset aSide mSide bigNumRule =
+    \f n → let rank    = (intLog n - offset) `div` base
+               base'   = fromIntegral base
+               offset' = fromIntegral offset
+               rank'   = fromIntegral rank
+               rankExp = (fix bigNumRule) rank
+               (m, a)  = n `divMod` E.scale base' offset' rank'
+               scale'  = E.scale base' offset' rankExp
+               mval    = doMul f m scale' mSide
+           in if E.isUnknown rankExp
+              then E.unknown
+              else if a ≡ 0
+                   then mval
+                   else (flipIfR aSide E.add) (f a) mval
+
+mulScale ∷ (Integral α, E.Scale α, E.Unknown β, E.Add β, E.Mul β, E.Scale β)
+         ⇒ α        -- ^ Base.
+         → α        -- ^ Offset.
+         → Side     -- ^ Add side.
+         → Side     -- ^ Mul side.
+         → Rule α β -- ^ Big num rule.
+         → Rule α β
+mulScale = mulScale_ $ \f m scale' mSide →
+                         case m of
+                           1 → scale'
+                           _ → (flipIfR mSide E.mul) (f m) scale'
+
+mulScale1 ∷ (Integral α, E.Scale α, E.Unknown β, E.Add β, E.Mul β, E.Scale β)
+          ⇒ α        -- ^ Base.
+          → α        -- ^ Offset.
+          → Side     -- ^ Add side.
+          → Side     -- ^ Mul side.
+          → Rule α β -- ^ Big num rule.
+          → Rule α β
+mulScale1 = mulScale_ $ \f m scale' mSide → (flipIfR mSide E.mul) (f m) scale'
+
+shortScale ∷ (Integral α, E.Scale α, E.Unknown β, E.Add β, E.Mul β, E.Scale β)
+           ⇒ Side     -- ^ Add side.
+           → Side     -- ^ Mul side.
+           → Rule α β -- ^ Big num rule.
+           → Rule α β
+shortScale = mulScale 3 3
+
+shortScale1 ∷ (Integral α, E.Scale α, E.Unknown β, E.Add β, E.Mul β, E.Scale β)
+            ⇒ Side     -- ^ Add side.
+            → Side     -- ^ Mul side.
+            → Rule α β -- ^ Big num rule.
+            → Rule α β
+shortScale1 = mulScale1 3 3
+
+longScale ∷ (Integral α, E.Scale α, E.Unknown β, E.Add β, E.Mul β, E.Scale β)
+          ⇒ Side     -- ^ Add side.
+          → Side     -- ^ Mul side.
+          → Rule α β -- ^ Big num rule.
+          → Rule α β
+longScale = mulScale 6 0
+
+longScale1 ∷ (Integral α, E.Scale α, E.Unknown β, E.Add β, E.Mul β, E.Scale β)
+           ⇒ Side     -- ^ Add side.
+           → Side     -- ^ Mul side.
+           → Rule α β -- ^ Big num rule.
+           → Rule α β
+longScale1 = mulScale1 6 0
+
+pelletierScale ∷ (Integral α, E.Scale α, E.Unknown β, E.Add β, E.Mul β, E.Scale β)
+               ⇒ Side     -- ^ Add side.
+               → Side     -- ^ Mul side.
+               → Rule α β -- ^ Big num rule.
+               → Rule α β
+pelletierScale aSide mSide bigNumRule =
+    conditional (\n → even $ intLog n `div` 3)
+                (mulScale 6 0 aSide mSide bigNumRule)
+                (mulScale 6 3 aSide mSide bigNumRule)
+
+pelletierScale1 ∷ (Integral α, E.Scale α, E.Unknown β, E.Add β, E.Mul β, E.Scale β)
+                ⇒ Side     -- ^ Add side.
+                → Side     -- ^ Mul side.
+                → Rule α β -- ^ Big num rule.
+                → Rule α β
+pelletierScale1 aSide mSide bigNumRule =
+    conditional (\n → even $ intLog n `div` 3)
+                (mulScale1 6 0 aSide mSide bigNumRule)
+                (mulScale1 6 3 aSide mSide bigNumRule)
+
+
+--------------------------------------------------------------------------------
+-- Miscellaneous
+--------------------------------------------------------------------------------
+
+flipIfR ∷ Side → (α → α → α) → (α → α → α)
+flipIfR L = id
+flipIfR R = flip
+
+mkIntervalList ∷ (Num a) ⇒ (a, b) → [(a, b)] → a → [((a, a), b)]
+mkIntervalList (k, r) krs end = go k r krs
+    where
+      go k1 r1 []            = [((k1, end), r1)]
+      go k1 r1 ((k2, r2):xs) = ((k1, k2-1), r1) : go k2 r2 xs
+
+mkIntervalMap ∷ (Ord v) ⇒ [((v, v), α)] → FT.IntervalMap v α
+mkIntervalMap = foldr ins FT.empty
+  where ins ((lo, hi), n) = FT.insert (FT.Interval lo hi) n
+
