module Text.Numeral.Language.EN
(
gb_entry
, us_entry
, gb_cardinal
, gb_ordinal
, gbPelletier_cardinal
, us_cardinal
, us_ordinal
, shortScaleStruct
, pelletierScaleStruct
, bounds
) where
import "base" Data.Bool ( otherwise )
import "base" Data.Function ( ($), const, fix )
import "base" Data.Maybe ( Maybe(Just) )
import "base" Data.Ord ( (<) )
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 "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 )
entry ∷ Entry
entry = emptyEntry
{ entIso639_1 = Just "en"
, entIso639_2 = ["eng"]
, entIso639_3 = Just "eng"
, entNativeNames = ["English"]
, entEnglishName = Just "English"
}
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")
(\_ _ → "illiard")
[]
us_cardinal ∷ (Inflection i, Integral α, E.Scale α) ⇒ i → α → Maybe Text
us_cardinal inf = render (cardinalRepr "negative " us_add) inf ∘ shortScaleStruct
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
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 α, E.Unknown β, E.Lit β, E.Add β, E.Mul β) ⇒ Rule α β
rule = findRule ( 0, lit )
[ ( 13, add 10 L )
, ( 20, mul 10 R L)
, ( 100, step1 100 10 R L)
, (1000, step1 1000 1000 R L)
]
(dec 6 1)
bounds ∷ (Integral α) ⇒ (α, α)
bounds = let x = dec 30003 1 in (negate x, x)
genericRepr ∷ (Exp i → Exp i → Ctx (Exp i) → Text)
→ Repr i
genericRepr f =
defaultRepr
{ reprAdd = Just f
, reprMul = Just (⊞)
}
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
→ (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 "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 _) _ | isOutside R c → "teenth"
| otherwise → "teen"
CtxMul R _ _ | isOutside R c → "tieth"
| otherwise → "ty"
_ | isOutside R c → "tenth"
| otherwise → "ten"
)
, (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
→ s
→ 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