numerals 0.1 → 0.3
raw patch · 49 files changed
+3458/−1820 lines, 49 filesdep +HUnitdep +base-unicode-symbolsdep +containersdep −bytestringdep −dstringdep −mtldep ~base
Dependencies added: HUnit, base-unicode-symbols, containers, containers-unicode-symbols, numerals-base, test-framework, test-framework-hunit
Dependencies removed: bytestring, dstring, mtl, pretty, text
Dependency ranges changed: base
Files
- LICENSE +1/−1
- README +0/−65
- README.markdown +74/−0
- TODO +0/−63
- Text/Numeral.hs +0/−166
- Text/Numeral/Debug.hs +0/−166
- Text/Numeral/Joinable.hs +0/−58
- Text/Numeral/Language.hs +0/−36
- Text/Numeral/Language/DE.hs +0/−60
- Text/Numeral/Language/EN.hs +0/−69
- Text/Numeral/Language/EO.hs +0/−44
- Text/Numeral/Language/FR.hs +0/−71
- Text/Numeral/Language/IT.hs +0/−77
- Text/Numeral/Language/JA.hs +0/−65
- Text/Numeral/Language/LA.hs +0/−75
- Text/Numeral/Language/NL.hs +0/−59
- Text/Numeral/Language/NO.hs +0/−63
- Text/Numeral/Language/PT.hs +0/−75
- Text/Numeral/Language/SP.hs +0/−80
- Text/Numeral/Language/SV.hs +0/−74
- Text/Numeral/Misc.hs +0/−20
- Text/Numeral/Pelletier.hs +0/−74
- Text/Numeral/Positional.hs +0/−97
- Text/Numeral/Roman.hs +0/−216
- numerals.cabal +163/−46
- src/Text/Numeral/Language/AMP.hs +88/−0
- src/Text/Numeral/Language/CHN.hs +76/−0
- src/Text/Numeral/Language/DE.hs +142/−0
- src/Text/Numeral/Language/EN.hs +146/−0
- src/Text/Numeral/Language/EO.hs +78/−0
- src/Text/Numeral/Language/ES.hs +167/−0
- src/Text/Numeral/Language/FR.hs +148/−0
- src/Text/Numeral/Language/GV.hs +108/−0
- src/Text/Numeral/Language/IT.hs +173/−0
- src/Text/Numeral/Language/JA.hs +223/−0
- src/Text/Numeral/Language/LA.hs +158/−0
- src/Text/Numeral/Language/MG.hs +111/−0
- src/Text/Numeral/Language/NL.hs +112/−0
- src/Text/Numeral/Language/NO.hs +96/−0
- src/Text/Numeral/Language/NQM.hs +81/−0
- src/Text/Numeral/Language/OJ.hs +97/−0
- src/Text/Numeral/Language/PT.hs +159/−0
- src/Text/Numeral/Language/RU.hs +155/−0
- src/Text/Numeral/Language/SCO.hs +97/−0
- src/Text/Numeral/Language/SV.hs +111/−0
- src/Text/Numeral/Language/TR.hs +156/−0
- src/Text/Numeral/Language/WO.hs +99/−0
- src/Text/Numeral/Language/YOR.hs +149/−0
- src/Text/Numeral/Language/ZH.hs +290/−0
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2009 Roel van Dijk, Bas van Dijk+Copyright © 2009—2011 Roel van Dijk, Bas van Dijk All rights reserved.
− README
@@ -1,65 +0,0 @@-Specialise-==========--This is a small note on the Specialise flag.--All the language definitions (Text.Numeral.Language.*) are polymorphic-in their stringlike type. For example:--> nl :: (IsString s, Joinable s) => NumConfig s--This allows the user to choose whatever stringlike type she wants.--If you turn on the Specialise flag then specialised versions of the-language definitions will be build:--> #ifdef DO_SPECIALISE-> import qualified Data.ByteString as B-> import qualified Data.DString as DS->-> {-# SPECIALISE nl :: NumConfig String #-}-> {-# SPECIALISE nl :: NumConfig B.ByteString #-}-> {-# SPECIALISE nl :: NumConfig DS.DString #-}-> #endif--The idea is that user code which uses any of the specialised types-will become more efficient because the overloading overhead has been-removed. Of course if we specialise the library will take longer to-compile and will be bigger.--The following will discuss some actual numbers:--Without Specialise-==================--$ cabal configure--$ time cabal build-...-5.347s--$ du -b dist/build/libHSnumerals-0.1.a-605574 dist/build/libHSnumerals-0.1.a---With Specialise-===============--$ cabal configure --flags="Specialise"--$ time cabal build-...-14.779s--$ du -b dist/build/libHSnumerals-0.1.a-2064852 dist/build/libHSnumerals-0.1.a---Conclusion-=========--If we specialise then:-* compilation will take almost 3 times longer-* the library will be at least 3 times bigger--TODO: Check for peformance gains!
+ README.markdown view
@@ -0,0 +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.++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:++ >>> import qualified Text.Numeral.Language.EN as EN+ >>> EN.uk_cardinal 123 :: Maybe String+ Just "one hundred and twenty-three"+ >>> EN.us_cardinal (10^50 + 42) :: Maybe String+ 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+ 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+ Nothing++Some languages have multiple scripts and methods for writing number+names. Take Chinese for example, which can be written using Han+characters or transcribed to the Latin script using Pinyin.++Traditional Chinese characters:++ >>> import qualified Text.Numeral.Language.ZH as ZH+ >>> ZH.trad_cardinal 123456 :: Maybe String+ Just "十二萬三千四百五十六"++Simplified characters for use in financial contexts:++ >>> ZH.finance_simpl_cardinal 123456 :: Maybe String+ Just "拾贰万参仟肆伯伍拾陆"++Transcribed using Pinyin:++ >>> ZH.pinyin_cardinal 123456 :: Maybe String+ Just "shíèrwàn sānqiān sìbǎi wǔshí liù"++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))))++Compare with:++ >>> NL.cardinal 123 :: Maybe String+ Just "honderddrieëntwintig"++100 (honderd) + (3 (drie) + (ën) 2 (twin) * 10 (tig))
− TODO
@@ -1,63 +0,0 @@-Also see: http://conway.rutgers.edu/~ccshan/wiki/blog/posts/WordNumbers1/--*** Features ***--Conversions between:- - Numbers and linguistic numerals- - Numbers and representations in numeral systems---*** Linguistic numerals ***--Cardinal numerals:- How many items - one, two, three--Ordinal numerals:- Position - first, second, third.- en 1 = first- en 2 = second- en 32 = thirty-second- nl 8 = achtste- nl 9 = negende- nl 89 = negenentachtigste--Partitive numerals:- Expresses a fraction - half, third, quarter.- en 1%2 = half- en 2%3 = two thirds- nl 2%3 = twee derden- nl 3%4 = drie kwart--Decimals:- Fractions of powers of ten- en 0.7 = seven-tenths- en 0.065 = sixty-five thousanths- nl 0.28 = achtentwintig honderdsten--Multiplicative numerals:- How many times - once, twice, thrice.- en 1 = once- en 2 = twice- en 3 = thrice- en [4..] = undefined - or use a convention like "four times,- five times, etc."--Distributive numerals:- Expresses a group of the number specified: In pairs, by the- dozen. English does not have distributive numerals for these but- other languages such as Georgian do.---*** Numeral systems ***--Positional systems:- Binary, octal, decimal, hexadecimal, vigesimal etc.- Also support floating point numbers.--Concatenative systems:- Roman numerals---*** TODOS ***--Use a package which defines polynomials for the positional numeral systems stuff.
− Text/Numeral.hs
@@ -1,166 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}--module Text.Numeral- ( -- *Types- NumConfig(..)- , NumSymbol(..)- , SymbolType(..)- , SymbolContext(..)- , Gender(..)-- -- *Cardinals- , cardinal- , findSym-- -- *Smart NumSymbol constructors- , term, add, mul- , termG, addG, mulG-- -- *Symbol representation helper functions- , gender, genderN- , tenForms, tenFormsG, tenForms', mulForms- )- where------------------------------------------------------------------------------------ Types----------------------------------------------------------------------------------data NumConfig s = NumConfig { ncCardinal :: Integer -> Maybe (NumSymbol s)- , ncNeg :: s -> s- , ncOne :: (Integer, s) -> s- , ncAdd :: (Integer, s) -> (Integer, s) -> s- , ncMul :: (Integer, s) -> (Integer, s) -> s- }--data NumSymbol s = NumSym { symType :: SymbolType- , symVal :: Integer- , symScope :: Integer- , symRepr :: Gender -> SymbolContext -> s- }--data SymbolType = Terminal | Add | Mul deriving Show--data SymbolContext = EmptyContext- | LA Integer SymbolContext- | RA Integer SymbolContext- | LM Integer SymbolContext- | RM Integer SymbolContext- deriving Show---- | Grammatical gender-data Gender = Neuter | Masculine | Feminine deriving Show-------------------------------------------------------------------------------------------------------------------------------------------------------------------cardinal :: NumConfig s -> Gender -> Integer -> Maybe s-cardinal NumConfig {..} g x | x < 0 = fmap ncNeg $ go EmptyContext $ abs x- | x == 0 = fmap (\sym -> symRepr sym g EmptyContext) $ ncCardinal 0- | otherwise = go EmptyContext x- where go ctx n = do (NumSym _ v _ rv) <- ncCardinal n- case n `divMod` v of- (1, 0) -> return $ ncOne (v, rv g ctx)- (1, r) -> do rs <- go (RA v ctx) r- return $ (v, ncOne (v, rv g (LA r ctx))) `ncAdd` (r, rs)- (q, r) | q >= v -> Nothing- | otherwise -> do qs <- go (LM v ctx) q- if r == 0- then return $ (q, qs) `ncMul` (v, rv g (RM q ctx))- else do let qv = q * v- rs <- go (RA qv ctx) r- return $ (qv, (q, qs) `ncMul` (v, rv g (RM q (LA qv ctx)))) `ncAdd` (r, rs)-------------------------------------------------------------------------------------------------------------------------------------------------------------------findSym :: [NumSymbol s] -> Integer -> Maybe (NumSymbol s)-findSym [] _ = Nothing-findSym (e:es) n = go e e es- where go :: NumSymbol s -> NumSymbol s -> [NumSymbol s] -> Maybe (NumSymbol s)- go a m [] = stop a m- go a m (x@(NumSym t v _ _) : xs)- | v == n = Just x- | otherwise = case t of- Terminal -> go a m xs- Add | v > n -> stop a m- | otherwise -> go x m xs- Mul | v > n -> stop a m- | otherwise -> go a x xs-- stop :: NumSymbol s -> NumSymbol s -> Maybe (NumSymbol s)- stop a@(NumSym {..}) m | n < symVal + symScope = return a- | otherwise = return m------------------------------------------------------------------------------------ Smart NumSymbol constructors----------------------------------------------------------------------------------termG :: Integer -> (Gender -> SymbolContext -> s) -> NumSymbol s-termG val fs = NumSym Terminal val 1 fs--addG :: Integer -> Integer -> (Gender -> SymbolContext -> s) -> NumSymbol s-addG scope val fs = NumSym Add scope val fs--mulG :: Integer -> (Gender -> SymbolContext -> s) -> NumSymbol s-mulG val fs = NumSym Mul val val fs--term :: Integer -> (SymbolContext -> s) -> NumSymbol s-term val fs = termG val $ const fs--add :: Integer -> Integer -> (SymbolContext -> s) -> NumSymbol s-add scope val fs = addG scope val $ const fs--mul :: Integer -> (SymbolContext -> s) -> NumSymbol s-mul val fs = mulG val $ const fs------------------------------------------------------------------------------------ Symbol representation helper functions------------------------------------------------------------------------------------ Differentiate between masculine and feminine genders. Other genders--- default to masculine.-gender :: s -> s -> (Gender -> s)-gender _ f Feminine = f-gender m _ _ = m---- Differentiate between neuter, masculine and feminine genders-genderN :: s -> s -> s -> (Gender -> s)-genderN n _ _ Neuter = n-genderN _ m _ Masculine = m-genderN _ _ f Feminine = f----- |Constructs a symbol representation based on the relation of the--- symbol with the number 10.--- The chosen representation depends on the context in which the--- symbol is used:--- d) default: x--- a) additive: 10 + x--- m) multiplicative: x * 10-tenForms :: s -> s -> s -> (SymbolContext -> s)-tenForms _ a _ (RA 10 _) = a-tenForms _ _ m (LM 10 _) = m-tenForms d _ _ _ = d--tenFormsG :: (Gender -> s) -> (Gender -> s) -> (Gender -> s) -> (Gender -> SymbolContext -> s)-tenFormsG d a m g ctx = tenForms (d g) (a g) (m g) ctx---- |Constructs a symbol representation based on the relation of the--- symbol with the number 10.--- The chosen representation depends on the context in which the--- symbol is used:--- d) default: x--- a) additive: 10 + x--- mt) multiplicative: x * 10--- mh) multiplicative: x * 100-tenForms' :: s -> s -> s -> s -> (SymbolContext -> s)-tenForms' _ a _ _ (RA 10 _) = a-tenForms' _ _ mt _ (LM 10 _) = mt-tenForms' _ _ _ mh (LM 100 _) = mh-tenForms' d _ _ _ _ = d--mulForms :: s -> s -> (SymbolContext -> s)-mulForms _ p (RM {}) = p-mulForms s _ _ = s
− Text/Numeral/Debug.hs
@@ -1,166 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE TypeSynonymInstances #-}--module Text.Numeral.Debug where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Misc (const2, withSnd)-import Text.Numeral.Language--import qualified Data.DString as DS-import qualified Data.ByteString.Char8 as B-import qualified Data.Text as T-import qualified Text.PrettyPrint as PP-----------------------------------------------------------------------------------class Stringable s where- toString :: s -> String--instance Stringable String where- toString = id--instance Stringable B.ByteString where- toString = B.unpack--instance Stringable T.Text where- toString = T.unpack--instance Stringable ShowS where- toString s = s []--instance Stringable DS.DString where- toString = DS.toString--instance Stringable PP.Doc where- toString = PP.render-----------------------------------------------------------------------------------type Test s = NumConfig s -> Gender -> [Integer] -> IO ()--test :: Stringable s => Test s-test nc g = mapM_ (putStrLn . pretty)- where pretty n = show n ++ " == " ++ (maybe "-" id $ fmap toString $ cardinal nc g n)--testS :: Test String-testS = test--testBS :: Test B.ByteString-testBS = test--testT :: Test T.Text-testT = test--testSS :: Test ShowS-testSS = test--testDS :: Test DS.DString-testDS = test--testDoc :: Test PP.Doc-testDoc = test--testDocWithStyle :: PP.Style -> NumConfig PP.Doc -> Gender -> [Integer] -> IO ()-testDocWithStyle s nc g = mapM_ (putStrLn . pretty)- where pretty n = show n ++ " == " ++ (maybe "-" id $ fmap (PP.renderStyle s) $ cardinal nc g n)------------------------------------------------------------------------------------- | @nummify@ transforms the given NumConfig to a numeric NumConfig--- such that 'prop_cardinal_nummify' holds. @nummify@ is thus usefull--- as a testing aid. @nummify@ is also usefull as a debugging aid--- when you use a suitable numeric type such as 'NS' which renders a--- numeric expression to a string representing the same expression.-nummify :: Num n => NumConfig s -> NumConfig n-nummify (NumConfig {..}) = NumConfig { ncCardinal = fmap transformSym . ncCardinal- , ncNeg = negate- , ncOne = snd- , ncAdd = withSnd (+)- , ncMul = withSnd (*)- }- where- -- Create a new symbol who's representation is its value.- transformSym :: (Num n) => NumSymbol s -> NumSymbol n- transformSym sym = sym { symRepr = const2 . fromInteger . symVal $ sym}---- | 'prop_cardinal_nummify' specifies the correctness of 'cardinal'.-prop_cardinal_nummify :: NumConfig String -> Gender -> Integer -> Bool-prop_cardinal_nummify nc g n = maybe True (== n) $ cardinal (nummify nc) g n------------------------------------------------------------------------------------- | 'NS' is used-newtype NS s = NS {unNS :: Precedence -> s}--type Precedence = Int---- The following bogus Show and Eq instances are needed for Num :-(--instance Show (NS s) where- show _ = "NS <function>"--instance Eq (NS s) where- _ == _ = False--instance (IsString s, Joinable s) => Num (NS s) where- fromInteger = NS . const . fromString . show-- (+) = bin "+" 6- (-) = bin "-" 6- (*) = bin "*" 7-- negate = un "negate"- abs = un "abs"- signum = un "signum"--un :: (IsString s, Joinable s) => s -> (NS s -> NS s)-un sFun x = NS $ \p -> paren (p > precApp)- (sFun <+> unNS x (precApp+1))- where- precApp = 10--bin :: (IsString s, Joinable s) => s -> Precedence -> (NS s -> NS s -> NS s)-bin sOp d x y = NS $ \p -> paren (p > d) $- let p' = d + 1- in unNS x p' <+> sOp <+> unNS y p'--paren :: (IsString s, Joinable s) => Bool -> s -> s-paren True s = "(" <> s <> ")"-paren False s = s--instance Stringable s => Stringable (NS s) where- toString (NS f) = toString $ f 0--testNSS :: Test (NS String)-testNSS = test--testNumS :: Test String-testNumS = testNSS . nummify-----------------------------------------------------------------------------------newtype Lst s = Lst {unLst :: [s]}--instance Joinable s => Joinable (Lst s) where- x <> y = Lst $ appendUnionWith (<>) (unLst x) (unLst y)- x <+> y = Lst $ unLst x ++ unLst y---- | appendUnionWith f [a, b, c] [d, e, f] => [a, b, c `f` d, e, f]-appendUnionWith :: (a -> a -> a) -> [a] -> [a] -> [a]-appendUnionWith _ [] ys = ys-appendUnionWith _ xs [] = xs-appendUnionWith f [x] (y:ys) = x `f` y : ys-appendUnionWith f (x:xs) ys = x : appendUnionWith f xs ys--instance IsString s => IsString (Lst s) where- fromString s = Lst [fromString s]--instance Stringable s => Stringable (Lst s) where- toString = show . map toString . unLst--testLst :: Test (Lst String)-testLst = test
− Text/Numeral/Joinable.hs
@@ -1,58 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TypeSynonymInstances #-}--module Text.Numeral.Joinable where--import Data.Monoid-import Data.String--import qualified Data.DString as DS-import qualified Data.ByteString.Char8 as B-import qualified Data.Text as T-import qualified Text.PrettyPrint as PP----- | Class of string-like types which can be joined.-class Joinable s where- (<>) :: s -> s -> s- (<+>) :: s -> s -> s--infixr 5 <>, <+>, <->--(<->) :: (Joinable s, IsString s) => s -> s -> s-x <-> y = x <> "-" <> y--space :: (Joinable s, IsString s) => s -> s -> s-space x y = x <> " " <> y--instance Joinable String where- (<>) = mappend- (<+>) = space--instance Joinable B.ByteString where- (<>) = mappend- (<+>) = space--instance Joinable T.Text where- (<>) = mappend- (<+>) = space--instance Joinable ShowS where- (<>) = mappend- (<+>) = space--instance Joinable DS.DString where- (<>) = mappend- (<+>) = space--instance Joinable PP.Doc where- (<>) = (PP.<>)- (<+>) = (PP.<+>)-----------------------------------------------------------------------------------instance IsString ShowS where- fromString = showString--instance IsString PP.Doc where- fromString = PP.text
− Text/Numeral/Language.hs
@@ -1,36 +0,0 @@-module Text.Numeral.Language- ( -- *West Germanic- module Text.Numeral.Language.NL- , module Text.Numeral.Language.DE- , module Text.Numeral.Language.EN- -- *North Germanic- , module Text.Numeral.Language.SV- , module Text.Numeral.Language.NO- -- *Romance- , module Text.Numeral.Language.FR- , module Text.Numeral.Language.IT- , module Text.Numeral.Language.LA- , module Text.Numeral.Language.PT- , module Text.Numeral.Language.SP- -- *Japonic- , module Text.Numeral.Language.JA- -- *Constructed- , module Text.Numeral.Language.EO- ) where--import Text.Numeral.Language.NL-import Text.Numeral.Language.DE-import Text.Numeral.Language.EN--import Text.Numeral.Language.SV-import Text.Numeral.Language.NO--import Text.Numeral.Language.FR-import Text.Numeral.Language.IT-import Text.Numeral.Language.LA-import Text.Numeral.Language.PT-import Text.Numeral.Language.SP--import Text.Numeral.Language.JA--import Text.Numeral.Language.EO
− Text/Numeral/Language/DE.hs
@@ -1,60 +0,0 @@--- -*- coding: utf-8 -*---{-# LANGUAGE CPP, OverloadedStrings #-}--module Text.Numeral.Language.DE (de) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Misc (d, withSnd)--#ifdef DO_SPECIALISE-import qualified Data.ByteString as B-import qualified Data.DString as DS--{-# SPECIALISE de :: NumConfig String #-}-{-# SPECIALISE de :: NumConfig B.ByteString #-}-{-# SPECIALISE de :: NumConfig DS.DString #-}-#endif--de :: (IsString s, Joinable s) => NumConfig s-de = NumConfig { ncNeg = ("minus" <+>)- , ncOne = deOne- , ncAdd = deAdd- , ncMul = withSnd (<>)- , ncCardinal = findSym deTable- }--deOne :: (IsString s, Joinable s) => (Integer, s) -> s-deOne (v, vs) | v >= (d 6) = "eine" <+> vs- | v >= 100 = "ein" <> vs- | otherwise = vs--deAdd :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-deAdd (x, x') (y, y') | x < 20 = y' <> x'- | x < 100 = (if y == 1- then "ein"- else y') <> "und" <> x'- | otherwise = x' <> y'--deTable :: (IsString s, Joinable s) => [NumSymbol s]-deTable = [ term 0 $ const "null"- , term 1 $ const "eins"- , term 2 $ tenForms "zwei" "zwei" "zwan"- , term 3 $ const "drei"- , term 4 $ const "vier"- , term 5 $ const "fünf"- , term 6 $ const "sechs"- , term 7 $ tenForms "sieben" "sieb" "sieb"- , term 8 $ const "acht"- , term 9 $ const "neun"- , mul 10 $ mulForms "zehn" "zig"- , term 11 $ const "elf"- , term 12 $ const "zwölf"- , add 30 10 $ const "dreißig"- , mul 100 $ const "hundert"- , mul 1000 $ const "tausend"- , mul (d 6) $ const "million"- , mul (d 9) $ const "milliarde"- ]
− Text/Numeral/Language/EN.hs
@@ -1,69 +0,0 @@-{-# LANGUAGE CPP, OverloadedStrings #-}--module Text.Numeral.Language.EN (enShort, enLong) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Pelletier (shortScale, longScale)--#ifdef DO_SPECIALISE-import qualified Data.ByteString as B-import qualified Data.DString as DS--{-# SPECIALISE enShort :: NumConfig String #-}-{-# SPECIALISE enShort :: NumConfig B.ByteString #-}-{-# SPECIALISE enShort :: NumConfig DS.DString #-}--{-# SPECIALISE enLong :: NumConfig String #-}-{-# SPECIALISE enLong :: NumConfig B.ByteString #-}-{-# SPECIALISE enLong :: NumConfig DS.DString #-}-#endif--enShort :: (IsString s, Joinable s) => NumConfig s-enShort = NumConfig { ncNeg = enNeg- , ncOne = enOne- , ncAdd = enAdd- , ncMul = enMul- , ncCardinal = findSym $ enTable ++ shortScale "illion"- }--enLong :: (IsString s, Joinable s) => NumConfig s-enLong = enShort { ncCardinal = findSym $ enTable ++ longScale "illion" "illiard"}--enNeg :: (IsString s, Joinable s) => s -> s-enNeg = ("minus" <+>)--enOne :: (IsString s, Joinable s) => (Integer, s) -> s-enOne (v, vs) | v >= 100 = "one" <+> vs- | otherwise = vs--enAdd :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-enAdd (x, x') (_, y') | x < 20 = y' <> x'- | x < 100 = x' <-> y'- | otherwise = x' <+> y'--enMul :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-enMul (_, x') (y, y') | y == 10 = x' <> y'- | otherwise = x' <+> y'--enTable :: (IsString s, Joinable s) => [NumSymbol s]-enTable = [ term 0 $ const "zero"- , term 1 $ const "one"- , term 2 $ tenForms "two" "twen" "twen"- , term 3 $ tenForms "three" "thir" "thir"- , term 4 $ tenForms "four" "four" "for"- , term 5 $ tenForms "five" "fif" "fif"- , term 6 $ const "six"- , term 7 $ const "seven"- , term 8 $ tenForms "eight" "eigh" "eigh"- , term 9 $ const "nine"- , mul 10 $ \ctx -> case ctx of- LA {} -> "teen"- RM {} -> "ty"- _ -> "ten"- , term 11 $ const "eleven"- , term 12 $ const "twelve"- , mul 100 $ const "hundred"- , mul 1000 $ const "thousand"- ]
− Text/Numeral/Language/EO.hs
@@ -1,44 +0,0 @@--- -*- coding: utf-8 -*---{-# LANGUAGE CPP, OverloadedStrings #-}--module Text.Numeral.Language.EO (eo) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Misc (d, withSnd)--#ifdef DO_SPECIALISE-import qualified Data.ByteString as B-import qualified Data.DString as DS--{-# SPECIALISE eo :: NumConfig String #-}-{-# SPECIALISE eo :: NumConfig B.ByteString #-}-{-# SPECIALISE eo :: NumConfig DS.DString #-}-#endif--eo :: (IsString s, Joinable s) => NumConfig s-eo = NumConfig { ncNeg = error "eoNeg: undefined"- , ncOne = snd- , ncAdd = withSnd (<+>)- , ncMul = withSnd (<>)- , ncCardinal = findSym eoTable- }--eoTable :: (IsString s, Joinable s) => [NumSymbol s]-eoTable = [ term 0 $ const "nulo"- , term 1 $ const "unu"- , term 2 $ const "du"- , term 3 $ const "tri"- , term 4 $ const "kvar"- , term 5 $ const "kvin"- , term 6 $ const "ses"- , term 7 $ const "sep"- , term 8 $ const "ok"- , term 9 $ const "naŭ"- , mul 10 $ const "dek"- , mul 100 $ const "cent"- , mul 1000 $ const "mil"- , mul (d 6) $ const "miliono"- ]
− Text/Numeral/Language/FR.hs
@@ -1,71 +0,0 @@--- -*- coding: utf-8 -*---{-# LANGUAGE CPP, OverloadedStrings #-}--module Text.Numeral.Language.FR (fr) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Pelletier (longScalePlural)--#ifdef DO_SPECIALISE-import qualified Data.ByteString as B-import qualified Data.DString as DS--{-# SPECIALISE fr :: NumConfig String #-}-{-# SPECIALISE fr :: NumConfig B.ByteString #-}-{-# SPECIALISE fr :: NumConfig DS.DString #-}-#endif---- Sources:--- http://www.cliffsnotes.com/WileyCDA/CliffsReviewTopic/Numbers.topicArticleId-25559,articleId-25469.html--fr :: (IsString s, Joinable s) => NumConfig s-fr = NumConfig { ncNeg = ("moins" <+>)- , ncOne = snd- , ncAdd = frAdd- , ncMul = frMul- , ncCardinal = findSym frTable- }--frAdd :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-frAdd (x, x') (y, y') | x == 10 && y < 7 = y' <> x'- | x < 80 && y == 1 = x' <+> "et" <+> y'- | x < 100 = x' <-> y'- | otherwise = x' <+> y'--frMul :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-frMul (_, x') (y, y') | y == 10 = x' <> y'- | otherwise = x' <+> y'--frTable :: (IsString s, Joinable s) => [NumSymbol s]-frTable = [ term 0 $ const "zéro"- , termG 1 $ tenFormsG (gender "un" "une") (const "on") (const "un")- , term 2 $ tenForms "deux" "deux" "dou"- , term 3 $ tenForms "trois" "trei" "tren"- , term 4 $ tenForms "quatre" "quator" "quar"- , term 5 $ tenForms "cinq" "quin" "cinqu"- , term 6 $ tenForms "six" "sei" "soix"- , term 7 $ const "sept"- , term 8 $ const "huit"- , term 9 $ const "neuf"- , mul 10 $ \ctx -> case ctx of- LA n _ | n < 7 -> "ze"- | otherwise -> "dix"- RM 3 _ -> "te"- RM _ _ -> "ante"- _ -> "dix"- , add 20 10 $ const "vingt"- , add 60 20 $ const "soixante"- , term 71 $ const "soixante et onze"- , term 80 $ const "quatre-vingts"- , add 80 20 $ const "quatre-vingt"- , mul 100 $ let c = "cent"- in \ctx -> case ctx of- RM _ (LA _ _) -> c- RM _ (LM _ _) -> c- RM _ _ -> c <> "s"- _ -> c- , mul 1000 $ const "mille"- ] ++ longScalePlural "illion" "illions" "illiard" "illiards"
− Text/Numeral/Language/IT.hs
@@ -1,77 +0,0 @@--- -*- coding: utf-8 -*---{-# LANGUAGE CPP, OverloadedStrings #-}--module Text.Numeral.Language.IT (it) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Misc (d)-import Text.Numeral.Pelletier (longScalePlural)--#ifdef DO_SPECIALISE-import qualified Data.ByteString as B-import qualified Data.DString as DS--{-# SPECIALISE it :: NumConfig String #-}-{-# SPECIALISE it :: NumConfig B.ByteString #-}-{-# SPECIALISE it :: NumConfig DS.DString #-}-#endif---- Sources:--- http://italian.about.com/library/weekly/aa042600a.htm--it :: (IsString s, Joinable s) => NumConfig s-it = NumConfig { ncNeg = error "itNeg: undefined"- , ncOne = snd- , ncAdd = itAdd- , ncMul = itMul- , ncCardinal = findSym itTable- }--itAdd :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-itAdd (x, x') (y, y') | x == 10 && y < 7 = y' <> x'- | y == 3 = x' <> "tré"- | otherwise = x' <> y'--itMul :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-itMul (_, x') (y, y') | y < d 6 = x' <> y'- | otherwise = x' <+> y'--itTable :: (IsString s, Joinable s) => [NumSymbol s]-itTable = [ term 0 $ const "zero"- , termG 1 $ tenFormsG (gender "uno" "una") (const "un") (const "uno")- , term 2 $ tenForms "due" "do" "due"- , term 3 $ tenForms "tre" "tre" "ten"- , term 4 $ tenForms "quattro" "quattor" "quar"- , term 5 $ tenForms "cinque" "quin" "cinqu"- , term 6 $ tenForms "sei" "se" "sess"- , term 7 $ tenForms "sette" "assette" "sett"- , term 8 $ tenForms "otto" "otto" "ott"- , term 9 $ tenForms "nove" "annove" "nove"- , mul 10 $ \ctx -> case ctx of- LA _ _ -> "dici"- RM 3 _ -> "ta"- RM _ _ -> "anta"- _ -> "dieci"- , add 20 10 $ const "venti"- , term 21 $ const "ventuno"- , term 28 $ const "ventotto"- , term 31 $ const "trentuno"- , term 38 $ const "trentotto"- , term 41 $ const "quarantuno"- , term 48 $ const "quarantotto"- , term 51 $ const "cinquantuno"- , term 58 $ const "cinquantotto"- , term 61 $ const "sessantuno"- , term 68 $ const "sessantotto"- , term 71 $ const "settantuno"- , term 78 $ const "settantotto"- , term 81 $ const "ottantuno"- , term 88 $ const "ottantotto"- , term 91 $ const "novantuno"- , term 98 $ const "novantotto"- , mul 100 $ const "cento"- , mul 1000 $ mulForms "mille" "mila"- ] ++ longScalePlural "ilione" "ilioni" "iliardo" "iliardi"
− Text/Numeral/Language/JA.hs
@@ -1,65 +0,0 @@--- -*- coding: utf-8 -*---{-# LANGUAGE CPP, OverloadedStrings #-}--module Text.Numeral.Language.JA (ja) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Misc (d, withSnd)--#ifdef DO_SPECIALISE-import qualified Data.ByteString as B-import qualified Data.DString as DS--{-# SPECIALISE ja :: NumConfig String #-}-{-# SPECIALISE ja :: NumConfig B.ByteString #-}-{-# SPECIALISE ja :: NumConfig DS.DString #-}-#endif--ja :: (IsString s, Joinable s) => NumConfig s-ja = NumConfig { ncNeg = ("mainasu" <+>)- , ncOne = jaOne- , ncAdd = withSnd (<+>)- , ncMul = withSnd (<->)- , ncCardinal = findSym jaTable- }--jaOne :: (IsString s, Joinable s) => (Integer, s) -> s-jaOne (v, vs) | v < 100 || (300 >= v && v < 400) = vs- | otherwise = "ichi" <-> vs--jaTable :: (IsString s, Joinable s) => [NumSymbol s]-jaTable = [ term 0 $ const "rei"- , term 1 $ const "ichi"- , term 2 $ const "ni"- , term 3 $ const "san"- , term 4 $ const "yon"- , term 5 $ const "go"- , term 6 $ const "roku"- , term 7 $ const "nana"- , term 8 $ const "hachi"- , term 9 $ const "kyū"- , mul 10 $ const "jū"- , mul 100 $ const "hyaku"- , add 300 100 $ const "san-byaku" -- rendaku- , mul 1000 $ const "sen"- , mul (d 4) $ const "man"- , mul (d 8) $ const "oku"- , mul (d 12) $ const "chō"- , mul (d 16) $ const "kei"- , mul (d 20) $ const "gai"- , mul (d 24) $ const "jo"- , mul (d 28) $ const "jō"- , mul (d 32) $ const "kō"- , mul (d 36) $ const "kan"- , mul (d 40) $ const "sei"- , mul (d 44) $ const "sai"- , mul (d 48) $ const "goku"- , mul (d 52) $ const "gōgasha"- , mul (d 56) $ const "asōgi"- , mul (d 60) $ const "nayuta"- , mul (d 64) $ const "fukashigi"- , mul (d 68) $ const "muryōtaisū"- ]
− Text/Numeral/Language/LA.hs
@@ -1,75 +0,0 @@-{-# LANGUAGE CPP, OverloadedStrings #-}--module Text.Numeral.Language.LA (la) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Misc (d)--#ifdef DO_SPECIALISE-import qualified Data.ByteString as B-import qualified Data.DString as DS--{-# SPECIALISE la :: NumConfig String #-}-{-# SPECIALISE la :: NumConfig B.ByteString #-}-{-# SPECIALISE la :: NumConfig DS.DString #-}-#endif--la :: (IsString s, Joinable s) => NumConfig s-la = NumConfig { ncNeg = error "laNeg: undefined"- , ncOne = snd- , ncAdd = laAdd- , ncMul = laMul- , ncCardinal = findSym laTable- }--laAdd :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-laAdd (x, x') (_, y') | x == 10 = y' <> x'- | otherwise = x' <+> y'--laMul :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-laMul (_, x') (y, y') | y < 1000 = x' <> y'- | otherwise = x' <+> y'--laTable :: (IsString s, Joinable s) => [NumSymbol s]-laTable = [ term 0 $ const "nulla"- , term 1 $ tenForms "unus" "un" "unus"- , term 2 $ tenForms' "duo" "duo" "vi" "du"- , term 3 $ tenForms' "tres" "tre" "tri" "tre"- , term 4 $ tenForms' "quattuor" "quattuor" "quadra" "quadri"- , term 5 $ tenForms' "quinque" "quin" "quinqua" "quin"- , term 6 $ tenForms' "sex" "se" "sexa" "ses"- , term 7 $ tenForms' "septem" "septen" "septua" "septin"- , term 8 $ const "octo"- , term 9 $ tenForms' "novem" "novem" "nona" "non"- , mul 10 $ \ctx -> case ctx of- LA _ _ -> "decim"- RM 2 _ -> "ginti"- RM _ _ -> "ginta"- _ -> "decem"- , term 18 $ const "duodeviginti"- , term 19 $ const "undeviginti"- , term 28 $ const "duodetriginta"- , term 29 $ const "undetriginta"- , term 38 $ const "duodequadraginta"- , term 39 $ const "undequadraginta"- , term 48 $ const "duodequinquaginta"- , term 49 $ const "undequinquaginta"- , term 58 $ const "duodesexaginta"- , term 59 $ const "undesexaginta"- , term 68 $ const "duodeseptuaginta"- , term 69 $ const "undeseptuaginta"- , term 78 $ const "duodeoctoginta"- , term 79 $ const "undeoctoginta"- , term 88 $ const "duodenonaginta"- , term 89 $ const "undenonaginta"- , term 98 $ const "duodecentum"- , term 99 $ const "undecentum"- , mul 100 $ \ctx -> case ctx of- RM n _ | n `elem` [2, 3, 6] -> "centi"- | otherwise -> "genti"- _ -> "centum"- , mul 1000 $ mulForms "mille" "millia"- , term (d 6) $ const "decies centena milia"- ]
− Text/Numeral/Language/NL.hs
@@ -1,59 +0,0 @@--- -*- coding: utf-8 -*---{-# LANGUAGE CPP, OverloadedStrings #-}--module Text.Numeral.Language.NL (nl) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Pelletier (longScale)--#ifdef DO_SPECIALISE-import qualified Data.ByteString as B-import qualified Data.DString as DS--{-# SPECIALISE nl :: NumConfig String #-}-{-# SPECIALISE nl :: NumConfig B.ByteString #-}-{-# SPECIALISE nl :: NumConfig DS.DString #-}-#endif--nl :: (IsString s, Joinable s) => NumConfig s-nl = NumConfig { ncNeg = ("min" <+>)- , ncOne = snd- , ncAdd = nlAdd- , ncMul = nlMul- , ncCardinal = findSym nlTable- }--nlAdd :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-nlAdd (x, x') (y, y') | x < 20 = y' <> x'- | x < 100 = y' <> (if y == 2 || y == 3- then "ën"- else "en")- <> x'- | otherwise = x' <+> y'--nlMul :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-nlMul (_, x') (y, y') | y <= 10 = x' <> y'- | otherwise = x' <+> y'--nlTable :: (IsString s, Joinable s) => [NumSymbol s]-nlTable = [ term 0 $ const "nul"- , term 1 $ const "één"- , term 2 $ tenForms "twee" "twin" "twin"- , term 3 $ tenForms "drie" "der" "der"- , term 4 $ tenForms "vier" "veer" "veer"- , term 5 $ const "vijf"- , term 6 $ const "zes"- , term 7 $ const "zeven"- , term 8 $ tenForms "acht" "tach" "acht"- , term 9 $ const "negen"- , mul 10 $ \ctx -> case ctx of- RM {} -> "tig"- _ -> "tien"- , term 11 $ const "elf"- , term 12 $ const "twaalf"- , mul 100 $ const "honderd"- , mul 1000 $ const "duizend"- ] ++ (longScale "iljoen" "iljard")
− Text/Numeral/Language/NO.hs
@@ -1,63 +0,0 @@--- -*- coding: utf-8 -*---{-# LANGUAGE CPP, OverloadedStrings #-}--module Text.Numeral.Language.NO (no) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Misc (d, withSnd)--#ifdef DO_SPECIALISE-import qualified Data.ByteString as B-import qualified Data.DString as DS--{-# SPECIALISE no :: NumConfig String #-}-{-# SPECIALISE no :: NumConfig B.ByteString #-}-{-# SPECIALISE no :: NumConfig DS.DString #-}-#endif---- Sources:--- http://en.wikibooks.org/wiki/Norwegian_Numbers--no :: (IsString s, Joinable s) => NumConfig s-no = NumConfig { ncNeg = error "noNeg: undefined"- , ncOne = noOne- , ncAdd = noAdd- , ncMul = withSnd (<>)- , ncCardinal = findSym noTable- }--noOne :: (IsString s, Joinable s) => (Integer, s) -> s-noOne (v, vs) | v >= (d 6) = "én" <+> vs- | otherwise = vs---- TODO: What are the rules for conjunction in Norse? When do you put--- "og" between numbers?-noAdd :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-noAdd (x, x') (_, y') | x < 20 = y' <> x'- | otherwise = x' <> y'--noTable :: (IsString s, Joinable s) => [NumSymbol s]-noTable = [ term 0 $ const "null"- , term 1 $ const "én"- , term 2 $ const "to"- , term 3 $ tenForms "tre" "tret" "tret"- , term 4 $ tenForms "fire" "fjor" "før"- , term 5 $ const "fem"- , term 6 $ const "seks"- , term 7 $ tenForms "sju" "syt" "syt"- , term 8 $ tenForms "åtte" "at" "åt"- , term 9 $ tenForms "ni" "nit" "nit"- , mul 10 $ \ctx -> case ctx of- LA {} -> "ten"- _ -> "ti"- , term 11 $ const "elleve"- , term 12 $ const "tolv"- , add 20 10 $ const "tjue"- , mul 100 $ const "hundre"- , mul (d 3) $ const "tusen"- , mul (d 6) $ mulForms "million" "millioner"- , mul (d 9) $ mulForms "milliard" "milliarder"- ]
− Text/Numeral/Language/PT.hs
@@ -1,75 +0,0 @@--- -*- coding: utf-8 -*---{-# LANGUAGE CPP, OverloadedStrings #-}--module Text.Numeral.Language.PT (pt) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Pelletier (shortScalePlural)--#ifdef DO_SPECIALISE-import qualified Data.ByteString as B-import qualified Data.DString as DS--{-# SPECIALISE pt :: NumConfig String #-}-{-# SPECIALISE pt :: NumConfig B.ByteString #-}-{-# SPECIALISE pt :: NumConfig DS.DString #-}-#endif---- Sources:--- http://www.sonia-portuguese.com/text/numerals.htm--- http://www.smartphrase.com/Portuguese/po_numbers_voc.shtml--pt :: (IsString s, Joinable s) => NumConfig s-pt = NumConfig { ncNeg = error "ptNeg: undefined"- , ncOne = ptOne- , ncAdd = ptAdd- , ncMul = ptMul- , ncCardinal = findSym ptTable- }--ptOne :: (IsString s, Joinable s) => (Integer, s) -> s-ptOne (x, x') | x <= 1000 = x'- | otherwise = "um" <+> x'---- TODO: When to use "e" is still unclear.-ptAdd :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-ptAdd (x, x') (_, y') | x == 10 = y' <> x'- | otherwise = x' <+> "e" <+> y'--ptMul :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-ptMul (_, x') (y, y') | y < 1000 = x' <> y'- | otherwise = x' <+> y'--ptTable :: (IsString s, Joinable s) => [NumSymbol s]-ptTable = [ term 0 $ const "zero"- , term 1 $ tenForms "um" "on" "um"- , term 2 $ tenForms "dois" "do" "dois"- , term 3 $ tenForms "três" "tre" "trin"- , term 4 $ tenForms "quatro" "cator" "quar"- , term 5 $ tenForms "cinco" "quin" "cinqü"- , term 6 $ tenForms "seis" "seis" "sess"- , term 7 $ tenForms "sete" "sete" "set"- , term 8 $ tenForms "oito" "oito" "oit"- , term 9 $ tenForms "nove" "nove" "nov"- , mul 10 $ \ctx -> case ctx of- LA _ _ -> "ze"- RM 3 _ -> "ta"- RM _ _ -> "enta"- _ -> "dez"- , term 16 $ const "dezesseis"- , term 17 $ const "dezessete"- , term 18 $ const "dezoito"- , term 19 $ const "dezenove"- , add 20 10 $ const "vinte"- , mul 100 $ \ctx -> case ctx of- RM _ _ -> "centos"- LA _ _ -> "cento"- _ -> "cem"- , add 200 100 $ const "duzentos"- , add 300 100 $ const "trezentos"- , add 500 100 $ const "quinhentos"- , mul 1000 $ const "mil"- ] ++ shortScalePlural "ilhão" "ilhões"
− Text/Numeral/Language/SP.hs
@@ -1,80 +0,0 @@--- -*- coding: utf-8 -*---{-# LANGUAGE CPP, OverloadedStrings #-}--module Text.Numeral.Language.SP (sp) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Misc (d)--#ifdef DO_SPECIALISE-import qualified Data.ByteString as B-import qualified Data.DString as DS--{-# SPECIALISE sp :: NumConfig String #-}-{-# SPECIALISE sp :: NumConfig B.ByteString #-}-{-# SPECIALISE sp :: NumConfig DS.DString #-}-#endif---- Sources:--- 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--sp :: (IsString s, Joinable s) => NumConfig s-sp = NumConfig { ncNeg = error "spNeg: undefined"- , ncOne = snd- , ncAdd = spAdd- , ncMul = spMul- , ncCardinal = findSym spTable- }--spAdd :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-spAdd (x, x') (y, y') | x == 10 && y < 6 = y' <> x'- | x == 10 = x' <> y'- | x < 30 = x' <> "i" <> y'- | x < 100 = x' <+> "y" <+> y'- | otherwise = x' <+> y'--spMul :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-spMul (_, x') (y, y') | y < 1000 = x' <> y'- | otherwise = x' <+> y'--spTable :: (IsString s, Joinable s) => [NumSymbol s]-spTable = [ term 0 $ const "cero"- , termG 1 $ tenFormsG (genderN "uno" "un" "una") (const "on") (const "uno")- , term 2 $ \ctx -> case ctx of- RA 10 _ -> "do"- RA 20 _ -> "dós"- _ -> "dos"- , term 3 $ \ctx -> case ctx of- RA n _ | n == 10 -> "tre"- | n < 100 -> "trés"- LM 10 _ -> "trein"- _ -> "tres"- , term 4 $ tenForms "cuatro" "cator" "cuaren"- , term 5 $ tenForms "cinco" "quin" "cincuen"- , term 6 $ \ctx -> case ctx of- RA n _ | n <= 20 -> "séis"- LM 10 _ -> "sesen"- _ -> "seis"- , term 7 $ tenForms' "siete" "siete" "seten" "sete"- , term 8 $ tenForms "ocho" "ocho" "ochen"- , term 9 $ tenForms' "nueve" "nueve" "noven" "novo"- , mul 10 $ \ctx -> case ctx of- LA n _ | n < 6 -> "ce"- | otherwise -> "dieci"- RM _ _ -> "ta"- _ -> "diez"- , add 20 10 $ const "veint"- , mul 100 $ \ctx -> case ctx of- RM _ _ -> "cientos"- LA _ _ -> "ciento"- _ -> "cien"- , add 500 100 $ const "quinientos"- , mul 1000 $ const "mil"- , mul (d 6) $ mulForms "millón" "millones"- , mul (d 12) $ mulForms "billón" "billones"- ]
− Text/Numeral/Language/SV.hs
@@ -1,74 +0,0 @@--- -*- coding: utf-8 -*---{-# LANGUAGE CPP, OverloadedStrings #-}--module Text.Numeral.Language.SV (sv) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Misc (d, withSnd)--#ifdef DO_SPECIALISE-import qualified Data.ByteString as B-import qualified Data.DString as DS--{-# SPECIALISE sv :: NumConfig String #-}-{-# SPECIALISE sv :: NumConfig B.ByteString #-}-{-# SPECIALISE sv :: NumConfig DS.DString #-}-#endif---- Sources:--- http://www.lysator.liu.se/language/Languages/Swedish/Grammar.html--- http://en.wikibooks.org/wiki/Swedish/Numerals--- http://longstrom.com/swedishtoenglish.htm#numbers---- http://www.cs.chalmers.se/~aarne/GF/--- http://www.cs.chalmers.se/~aarne/GF/lib/resource/norwegian/NumeralNor.gf--sv :: (IsString s, Joinable s) => NumConfig s-sv = NumConfig { ncNeg = ("minus" <+>)- , ncOne = svOne- , ncAdd = svAdd- , ncMul = withSnd (<>)- , ncCardinal = findSym svTable- }--svOne :: (IsString s, Joinable s) => (Integer, s) -> s-svOne (v, vs) | v >= 100 = "ett" <> vs- | otherwise = vs--svAdd :: (IsString s, Joinable s) => (Integer, s) -> (Integer, s) -> s-svAdd (x, x') (_, y') | x < 20 = y' <> x'- | otherwise = x' <> y'--svTable :: (IsString s, Joinable s) => [NumSymbol s]-svTable = [ term 0 $ const "noll"- , term 1 $ const "ett"- , term 2 $ const "två"- , term 3 $ tenForms "tre" "tret" "tret"- , term 4 $ tenForms "fyra" "fjor" "fyr"- , term 5 $ const "fem"- , term 6 $ const "sex"- , term 7 $ tenForms "sju" "sjut" "sjut"- , term 8 $ tenForms "åtta" "ar" "åt"- , term 9 $ tenForms "nio" "nit" "nit"- , mul 10 $ \ctx -> case ctx of- LA {} -> "ton"- _ -> "tio"- , term 11 $ const "elva"- , term 12 $ const "tolv"- , add 20 10 $ const "tjugo"- , mul 100 $ const "hundra"- , mul (d 3) $ const "tusen"- , mul (d 6) $ mulForms "miljon" "miljoner"- , mul (d 9) $ mulForms "miljard" "miljarder"- , mul (d 12) $ mulForms "biljon" "biljoner"- , mul (d 15) $ mulForms "biljard" "biljarder"- , mul (d 18) $ mulForms "triljon" "triljoner"- , mul (d 21) $ mulForms "triljard" "triljarder"- , mul (d 24) $ mulForms "kvadriljon" "kvadriljoner"- , mul (d 27) $ mulForms "kvadriljard" "kvadriljarder"- , mul (d 30) $ mulForms "kvintriljon" "kvintriljoner"- , mul (d 33) $ mulForms "kvintriljard" "kvintriljarder"- ]
− Text/Numeral/Misc.hs
@@ -1,20 +0,0 @@-module Text.Numeral.Misc where---withSnd :: (a -> b -> c) -> (d, a) -> (e, b) -> c-withSnd f (_, x) (_, y) = f x y--d :: Integer -> Integer-d = (10 ^)--const2 :: a -> b -> c -> a-const2 = const . const--weave :: [a] -> [a] -> [a]-weave [] ys = ys-weave (x:xs) ys = x : weave ys xs--untilNothing :: [Maybe a] -> [a]-untilNothing [] = []-untilNothing (Just x : xs) = x : untilNothing xs-untilNothing (Nothing : _) = []
− Text/Numeral/Pelletier.hs
@@ -1,74 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--module Text.Numeral.Pelletier- ( longScale- , longScalePlural- , shortScale- , shortScalePlural- ) where--import Data.String-import Text.Numeral-import Text.Numeral.Joinable-import Text.Numeral.Misc (d, untilNothing, weave, withSnd)---longScale :: (IsString s, Joinable s) => s -> s -> [NumSymbol s]-longScale a b = longScalePlural a a b b--longScalePlural :: (IsString s, Joinable s) => s -> s -> s -> s -> [NumSymbol s]-longScalePlural a as b bs = untilNothing $ weave (map illion [1..]) (map illiard [1..])- where illion n = fmap (\s -> mul (d 6 ^ n) $ mulForms (s <> a) (s <> as)) $ bigCardinal n- illiard n = fmap (\s -> mul (d 6 ^ n * d 3) $ mulForms (s <> b) (s <> bs)) $ bigCardinal n--shortScale :: (IsString s, Joinable s) => s -> [NumSymbol s]-shortScale a = shortScalePlural a a--shortScalePlural :: (IsString s, Joinable s) => s -> s -> [NumSymbol s]-shortScalePlural a as = untilNothing $ map illion [1..]- where illion n = fmap (\s -> mul (d 3 * (d 3 ^ n)) $ mulForms (s <> a) (s <> as)) $ bigCardinal n--bigCardinal :: (IsString s, Joinable s) => Integer -> Maybe s-bigCardinal = cardinal bigNum Masculine------------------------------------------------------------------------------------- Big Num 'language'----------------------------------------------------------------------------------bigNum :: (IsString s, Joinable s) => NumConfig s-bigNum = NumConfig { ncNeg = error "bigNumNeg: undefined"- , ncOne = snd- , ncAdd = withSnd . flip $ (<>)- , ncMul = withSnd (<>)- , ncCardinal = findSym bigNumTable- }--bigNumTable :: (IsString s, Joinable s) => [NumSymbol s]-bigNumTable = [ term 0 $ const "nulla"- , term 1 $ forms "m" "un" "un" "mi" "mi"- , term 2 $ forms "b" "duo" "duo" "vi" "du"- , term 3 $ forms "tr" "tre" "tres" "tri" "tre"- , term 4 $ forms "quadr" "quattuor" "quattuor" "quadra" "quadrin"- , term 5 $ forms "quint" "quin" "quinqua" "quinqua" "quin"- , term 6 $ forms "sext" "sex" "ses" "sexa" "ses"- , term 7 $ forms "sept" "septen" "septem" "septua" "septin"- , term 8 $ forms "oct" "octo" "octo" "octo" "octin"- , term 9 $ forms "non" "novem" "novem" "nona" "non"- , mul 10 $ \ctx -> case ctx of- RM {} -> "gint"- _ -> "dec"- , mul 100 $ \ctx -> case ctx of- RM n _ | n `elem` [2, 3, 6] -> "cent"- | otherwise -> "gent"- _ -> "cent"- , mul 1000 $ const "mill"- , mul 10000 $ const "myr"- ]- where forms d a1 a2 m1 m2 ctx = case ctx of- RA 10 _ -> a1- RA _ _ -> a2- LM 100 _ -> m2- LM _ _ -> m1- _ -> d-
− Text/Numeral/Positional.hs
@@ -1,97 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE BangPatterns #-}--module Text.Numeral.Positional- ( toPositional- , digitSymbol-- -- *Positional numeral systems- , binary- , negabinary- , ternary- , octal- , decimal- , negadecimal- , hexadecimal- ) where--import qualified Data.List as L-import Data.Monoid-import Data.String------------------------------------------------------------------------------------toPolynomial :: Integer -> Integer -> [Integer]-toPolynomial b n | n == 0 = [0]- | b == 0 = error "toPolynomial: base 0"- | b == (-1) = case n of- (-1) -> [0, 1]- 1 -> [1]- _ -> error "toPolynomial: base (-1)"- | b == 1 = L.genericReplicate (abs n) (signum n)- | otherwise = toPolynomial_b $ n- where toPolynomial_b 0 = []- toPolynomial_b n = let (q, r) = n `qr` b- in r : toPolynomial_b q-- qr | b > 0 = quotRem- | otherwise = quotRem'-- quotRem' :: Integral a => a -> a -> (a, a)- quotRem' n d = let qr@(q, r) = n `quotRem` d- in if r < 0- then (q + 1, r - d)- else qr--fromPolynomial :: Integer -> [Integer] -> Integer-fromPolynomial b = sum' . zipWith (*) (iterate (* b) 1)- where sum' = L.foldl' (+) 0--prop_polynomial :: Integer -> Integer -> Bool-prop_polynomial b n | b == 0 && n /= 0 = True- | b == (-1) && abs n > 1 = True- | otherwise = n == (fromPolynomial b $ toPolynomial b n)-----------------------------------------------------------------------------------toPositional :: (IsString s, Monoid s) => (Integer -> s) -> Integer -> Integer -> Maybe s-toPositional f b n | b == 0 = Nothing- | n < 0 && b > 0 = fmap (mappend "-") $ repr (abs n)- | otherwise = repr n- where repr x = fmap mconcat . mapM f' . reverse . toPolynomial b $ x- f' n | n >= abs b = Nothing- | otherwise = Just $ f n------------------------------------------------------------------------------------- Digit symbols up to base 62.--- TODO: array for faster lookup-digitSymbols :: IsString s => [s]-digitSymbols = map (\x -> fromString [x]) $ ['0'..'9'] ++ ['A'..'Z'] ++ ['a'..'z']--digitSymbol :: IsString s => Integer -> s-digitSymbol = (digitSymbols `L.genericIndex`)-----------------------------------------------------------------------------------binary :: (Monoid s, IsString s) => Integer -> Maybe s-binary = toPositional digitSymbol 2--negabinary :: (Monoid s, IsString s) => Integer -> Maybe s-negabinary = toPositional digitSymbol (-2)--ternary :: (Monoid s, IsString s) => Integer -> Maybe s-ternary = toPositional digitSymbol 3--octal :: (Monoid s, IsString s) => Integer -> Maybe s-octal = toPositional digitSymbol 8--decimal :: (Monoid s, IsString s) => Integer -> Maybe s-decimal = toPositional digitSymbol 10--negadecimal :: (Monoid s, IsString s) => Integer -> Maybe s-negadecimal = toPositional digitSymbol (-10)--hexadecimal ::(Monoid s, IsString s) => Integer -> Maybe s-hexadecimal = toPositional digitSymbol 16
− Text/Numeral/Roman.hs
@@ -1,216 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE OverloadedStrings #-}--{-| Parsing and pretty printing of Roman numerals.-- This module provides functions for parsing and pretty printing Roman- numerals. Because the notation of Roman numerals has varied through- the centuries this package allows for some customisation using a- configuration that is passed to the conversion functions. Exceptions- are dealt with by wrapping the results of conversions in the error- monad.--}-module Text.Numeral.Roman- ( -- * Types- NumeralConfig(..)- -- * Sample configurations- , modernRoman- , simpleRoman- -- * Pretty printing- , convertTo- , unsafeConvertTo- , toRoman- , unsafeToRoman- -- * Parsing- , convertFrom- , fromRoman- , unsafeConvertFrom- , unsafeFromRoman- ) where--import Control.Monad.Error-import qualified Data.ByteString as BS-import qualified Data.List as L-import Data.Monoid-import Data.String-import Prelude hiding (null)-import qualified Prelude as P------------------------------------------------------------------------------------ Types------------------------------------------------------------------------------------ |A configuration with which the 'convertTo' and 'convertFrom'--- functions can be parameterized.-data NumeralConfig s n = NC { -- |The largest value that can be- -- represented using this configuration.- ncMax :: n- -- |Symbol to represent the value 0. The- -- Romans did not have a symbol for- -- zero. If set to Nothing a- -- 'convertFrom' 0 will throw an error.- , ncZero :: Maybe s- -- |A table of symbols and their- -- numerical values. The table must be- -- ordered with the largest symbols- -- appearing first. If any symbol is- -- the empty string then 'convertFrom'- -- will be undefined. If any symbol in- -- this table is associated with the- -- value 0 both the convertTo and- -- 'convertFrom' function will be- -- undefined.- , ncTable :: [(s, n)]- }------------------------------------------------------------------------------------ Default tables------------------------------------------------------------------------------------ |Configuration for Roman numerals as they are commonly used--- today. The value 0 is represented by the empty string. It can be--- interpreted as not writing down a number. This configuration is--- limited to the range [1..3999]. Larger numbers can be represented--- using Roman numerals but you will need notations that are hard or--- impossible to express using strings.-modernRoman :: (IsString s, Ord n, Num n) => NumeralConfig s n-modernRoman = NC { ncMax = 3999- , ncZero = Just ""- , ncTable = [ ("M", 1000)- , ("CM", 900)- , ("D", 500)- , ("CD", 400)- , ("C", 100)- , ("XC", 90)- , ("L", 50)- , ("XL", 40)- , ("X", 10)- , ("IX", 9)- , ("V", 5)- , ("IV", 4)- , ("I", 1)- ]- }---- |Configuration for Roman numerals that do not use the rule that a--- lower rank symbol can be placed before a higher rank symbol to--- denote the difference between them. Thus a numeral like "IV" will--- not be accepted or generated by this configuration.-simpleRoman :: (IsString s, Ord n, Num n) => NumeralConfig s n-simpleRoman = NC { ncMax = 3999- , ncZero = Just ""- , ncTable = [ ("M", 1000)- , ("D", 500)- , ("C", 100)- , ("L", 50)- , ("X", 10)- , ("V", 5)- , ("I", 1)- ]- }------------------------------------------------------------------------------------ Pretty printing------------------------------------------------------------------------------------ |Converts a number to a Roman numeral according to the given--- configuration. Numbers which are out of bounds will cause--- exceptions to be thrown. An exception will also be raised if no--- representation is possible with the given configuration. If the--- value of any symbol in the configuration is equal to 0 or a symbol--- is the empty string this function is undefined.-convertTo :: (Monoid s, Ord n, Num n, MonadError String m)- => NumeralConfig s n -> n -> m s-convertTo nc n | n < 0 = throwError "Roman.convertTo: can't represent negative numbers"- | n > maxN = throwError $ "Roman.convertTo: too large (max = " ++ (show maxN) ++ ")"- | n == 0 = maybe (throwError "Roman.convertTo: no symbol for zero")- return- $ ncZero nc- | otherwise = go n $ ncTable nc- where maxN = ncMax nc- go 0 _ = return mempty- go _ [] = throwError "Roman.convertTo: out of symbols"- go n tab@(~(sym, val) : ts) | n >= val = liftM2 mappend (return sym) $ go (n - val) tab- | otherwise = go n ts---- |Like 'convertTo', but exceptions are promoted to errors.-unsafeConvertTo :: (Monoid s, Ord n, Num n) => NumeralConfig s n -> n -> s-unsafeConvertTo nc = either error id . convertTo nc---- |Converts a number to a modern Roman numeral. See 'convertTo' for--- possible exceptions.-toRoman :: (IsString s, Monoid s, Ord n, Num n, MonadError String m) => n -> m s-toRoman = convertTo modernRoman---- |Like 'toRoman', but exceptions are promoted to errors.-unsafeToRoman :: (IsString s, Monoid s, Ord n, Num n) => n -> s-unsafeToRoman = unsafeConvertTo modernRoman------------------------------------------------------------------------------------ Parsing------------------------------------------------------------------------------------ |Class used to overload the input of the parsing functions.-class StripPrefix s where- null :: s -> Bool- stripPrefix :: s -> s -> Maybe s--instance Eq a => StripPrefix [a] where- null = P.null- stripPrefix = L.stripPrefix--instance StripPrefix BS.ByteString where- null = BS.null- stripPrefix p s = let (h, t) = BS.breakSubstring p s- in if null h- then Just $ BS.drop (BS.length p) t- else Nothing---- |Parses a string as a Roman numeral according to the given--- configuration. An exception will be raised if the input is not a--- valid numeral.-convertFrom :: (Monoid s, StripPrefix s, Eq s, Ord n, Num n, MonadError String m)- => NumeralConfig s n -> s -> m n-convertFrom nc s | maybe False (== s) (ncZero nc) = return 0- | otherwise = do n <- (go 0 (ncTable nc) s)- s' <- convertTo nc n- if s == s'- then return n- else throwError "Roman.convertFrom: invalid Roman numeral"- where go n _ s | null s = return n- go _ [] s = throwError $ "Roman.convertFrom: can't parse"- go n tab@((sym, val) : ts) s = maybe (go n ts s)- (go (n + val) tab)- $ stripPrefix sym s---- |Like 'convertFrom', but exceptions are promoted to errors.-unsafeConvertFrom :: (Monoid s, StripPrefix s, Eq s, Ord n, Num n)- => NumeralConfig s n -> s -> n-unsafeConvertFrom nc = either error id . convertFrom nc---- |Parses a string as a modern Roman numeral. See 'convertFrom' for--- possible exceptions.-fromRoman :: (IsString s, Monoid s, StripPrefix s, Eq s, Ord n, Num n, MonadError String m)- => s -> m n-fromRoman = convertFrom modernRoman---- |Like 'fromRoman', but exceptions are promoted to errors.-unsafeFromRoman :: (IsString s, Monoid s, StripPrefix s, Eq s, Ord n, Num n)- => s -> n-unsafeFromRoman = unsafeConvertFrom modernRoman------------------------------------------------------------------------------------ Properties----------------------------------------------------------------------------------prop_printParseIsId :: NumeralConfig String Integer -> String -> Bool-prop_printParseIsId nc xs = either (const True) id- $ do n <- convertFrom nc xs- xs' <- convertTo nc n- return $ xs' == xs--prop_parsePrintIsId :: NumeralConfig String Integer -> Integer -> Bool-prop_parsePrintIsId nc n = either (const True) id- $ do xs <- convertTo nc n- n' <- convertFrom nc xs- return $ n' == n
numerals.cabal view
@@ -1,60 +1,177 @@ name: numerals-version: 0.1-cabal-version: >= 1.6+version: 0.3+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>, Bas van Dijk <v.dijk.bas@gmail.com>-copyright: (c) 2009 Roel van Dijk, Bas van Dijk+maintainer: Roel van Dijk <vandijk.roel@gmail.com>+copyright: 2009–2011 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: Utilities for working with numerals-description:+synopsis: Convert numbers to number words+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.+ .+ 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:+ .+ >>> import qualified Text.Numeral.Language.EN as EN+ >>> EN.uk_cardinal 123 :: Maybe String+ Just "one hundred and twenty-three"+ >>> EN.us_cardinal (10^50 + 42) :: Maybe String+ 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+ 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+ Nothing+ .+ Some languages have multiple scripts and methods for writing number+ names. Take Chinese for example, which can be written using Han+ characters or transcribed to the Latin script using Pinyin.+ .+ Traditional Chinese characters:+ .+ >>> import qualified Text.Numeral.Language.ZH as ZH+ >>> ZH.trad_cardinal 123456 :: Maybe String+ Just "十二萬三千四百五十六"+ .+ Simplified characters for use in financial contexts:+ .+ >>> ZH.finance_simpl_cardinal 123456 :: Maybe String+ Just "拾贰万参仟肆伯伍拾陆"+ .+ Transcribed using Pinyin:+ .+ >>> ZH.pinyin_cardinal 123456 :: Maybe String+ Just "shíèrwàn sānqiān sìbǎi wǔshí liù"+ .+ 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))))+ .+ Compare with:+ .+ >>> NL.cardinal 123 :: Maybe String+ Just "honderddrieëntwintig"+ .+ 100 (honderd) + (3 (drie) + (ën) 2 (twin) * 10 (tig)) -extra-source-files: ./TODO- , ./README- , ./LICENSE- , ./Text/Numeral/Debug.hs+extra-source-files: ./README.markdown -flag specialise- description: Specialise the polymorphic language definitions to some- often used types (String, ByteString, DString). Note- that this increases compilation time and the size of- the object files significantly.- Also see README- default: False+------------------------------------------------------------------------------- +source-repository head+ Type: git+ Location: git://github.com/roelvandijk/numerals.git++-------------------------------------------------------------------------------+ library- if flag(specialise)- CPP-Options: -DDO_SPECIALISE+ hs-source-dirs: src+ ghc-options: -Wall - GHC-Options: -O2+ 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 >=2- , mtl ==1.1.*- , dstring <0.3- , pretty >=1 && <1.1- , text >=0.1 && <0.2- , bytestring >=0.9 && <1+ exposed-modules: Text.Numeral.Language.AMP+ , Text.Numeral.Language.CHN+ , Text.Numeral.Language.DE+ , Text.Numeral.Language.EN+ , Text.Numeral.Language.EO+ , Text.Numeral.Language.ES+ , Text.Numeral.Language.FR+ , Text.Numeral.Language.GV+ , Text.Numeral.Language.IT+ , Text.Numeral.Language.JA+ , Text.Numeral.Language.LA+ , 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.PT+ , Text.Numeral.Language.RU+ , Text.Numeral.Language.SCO+ , Text.Numeral.Language.SV+ , Text.Numeral.Language.TR+ , Text.Numeral.Language.WO+ , Text.Numeral.Language.YOR+ , Text.Numeral.Language.ZH - exposed-modules: Text.Numeral- , Text.Numeral.Language- , Text.Numeral.Language.NL- , Text.Numeral.Language.DE- , Text.Numeral.Language.EN- , Text.Numeral.Language.SV- , Text.Numeral.Language.NO- , Text.Numeral.Language.FR- , Text.Numeral.Language.IT- , Text.Numeral.Language.LA- , Text.Numeral.Language.PT- , Text.Numeral.Language.SP- , Text.Numeral.Language.JA- , Text.Numeral.Language.EO- , Text.Numeral.Pelletier- , Text.Numeral.Positional- , Text.Numeral.Roman- , Text.Numeral.Joinable- , Text.Numeral.Misc- -- , Text.Numeral.Debug+-------------------------------------------------------------------------------++test-suite test-numerals+ type: exitcode-stdio-1.0+ main-is: test.hs+ hs-source-dirs: src, test++ other-modules: Text.Numeral.Language.CHN.TestData+ , Text.Numeral.Language.AMP.TestData+ , Text.Numeral.Language.DE.TestData+ , Text.Numeral.Language.EN.TestData+ , Text.Numeral.Language.EO.TestData+ , Text.Numeral.Language.ES.TestData+ , Text.Numeral.Language.FR.TestData+ , Text.Numeral.Language.GV.TestData+ , Text.Numeral.Language.IT.TestData+ , Text.Numeral.Language.JA.TestData+ , Text.Numeral.Language.LA.TestData+ , Text.Numeral.Language.MG.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.PT.TestData+ , Text.Numeral.Language.RU.TestData+ , Text.Numeral.Language.SCO.TestData+ , Text.Numeral.Language.SV.TestData+ , Text.Numeral.Language.TR.TestData+ , Text.Numeral.Language.WO.TestData+ , Text.Numeral.Language.YOR.TestData+ , Text.Numeral.Language.ZH.TestData+ ghc-options: -Wall++ 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+ , HUnit >= 1.2.2 && < 1.3+ , test-framework >= 0.3.3 && < 0.5+ , test-framework-hunit >= 0.2.6 && < 0.3+
+ src/Text/Numeral/Language/AMP.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] -++[@ISO639-2@] -++[@ISO639-3@] amp++[@Native name@] -++[@English name@] Alamblak+-}++module Text.Numeral.Language.AMP+ ( cardinal+ , struct+ ) 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+++-------------------------------------------------------------------------------+-- AMP+-------------------------------------------------------------------------------++{-+Sources:+ http://www.sf.airnet.ne.jp/~ts/language/number/alamblak.html+-}++cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β+struct = checkPos+ $ fix+ $ findRule ( 1, lit )+ [ ( 3, add 2 R )+ , ( 5, lit )+ , ( 6, add 5 R )+ , (10, mul 5 R R)+ , (20, lit )+ , (21, add 20 R )+ , (40, mul 20 R R)+ ]+ 399++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just (⊞)+ , reprMul = Just $ \_ _ _ → " "+ }+ where+ (Lit 2 ⊞ Lit _) _ = "i"+ (_ ⊞ _ ) _ = "i "++ syms =+ M.fromList+ [ (1, const "rpat")+ , (2, const "hosf")+ , (5, \c → case c of+ CtxMul L _ _ → "tir"+ _ → "tir yohtt"+ )+ , (20, \c → case c of+ CtxMul L _ _ → "yima"+ _ → "yima yohtt"+ )+ ]
+ src/Text/Numeral/Language/CHN.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] -++[@ISO639-2B@] chn++[@ISO639-3@] chn++[@Native name@] -++[@English name@] Chinook Jargon+-}++module Text.Numeral.Language.CHN+ ( cardinal+ , struct+ ) 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+++--------------------------------------------------------------------------------+-- CHN+--------------------------------------------------------------------------------++cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β+struct = checkPos+ $ fix+ $ findRule ( 0, lit )+ [ ( 11, step 10 10 R L)+ , (100, lit )+ ]+ 100++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just $ \_ _ _ → " pe "+ , reprMul = Just $ \_ _ _ → " "+ }+ where+ syms =+ M.fromList+ [ (1, const "ikt")+ , (2, const "mokst")+ , (3, const "klone")+ , (4, const "lakit")+ , (5, const "kwinnum")+ , (6, const "taghum")+ , (7, const "sinamokst")+ , (8, const "stotekin")+ , (9, const "kwaist")+ , (10, const "tahtlum")+ , (100, const "tukamonuk")+ ]
+ src/Text/Numeral/Language/DE.hs view
@@ -0,0 +1,142 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] de++[@ISO639-2B@] ger++[@ISO639-3@] deu++[@Native name@] Deutsch++[@English name@] German+-}++module Text.Numeral.Language.DE+ ( cardinal+ , struct+ ) 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.String ( IsString )+import "base" Prelude ( Integral, (-), Integer )+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )+import "base-unicode-symbols" Data.List.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.BigNum as BN+import qualified "numerals-base" Text.Numeral.Exp.Classes as C+++-------------------------------------------------------------------------------+-- DE+-------------------------------------------------------------------------------++{-+Sources:+ http://de.wikipedia.org/wiki/Zahlennamen+-}++cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ ( Integral α, C.Scale α+ , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β+ )+ ⇒ α → β+struct = pos $ fix $ rule `combine` pelletierScale R L BN.rule+ 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)++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 "+ }+ where+ (_ ⊞ (_ `Mul` Lit 10)) _ = "und"+ (_ ⊞ _ ) _ = ""++ syms =+ M.fromList+ [ (0, const "null")+ , (1, \c → case c of+ CtxAdd {} → "ein"+ CtxMul _ (Lit n) _+ | n ≥ dec 6 → "eine"+ | n ≥ 100 → "ein"+ _ → "eins"+ )+ , (2, \c → case c of+ CtxMul _ (Lit 10) _ → "zwan"+ _ → "zwei"+ )+ , (3, const "drei")+ , (4, const "vier")+ , (5, const "fünf")+ , (6, \c → case c of+ CtxAdd _ (Lit 10) _ → "sech"+ CtxMul _ (Lit 10) _ → "sech"+ _ → "sechs"+ )+ , (7, \c → case c of+ CtxAdd _ (Lit 10) _ → "sieb"+ CtxMul _ (Lit 10) _ → "sieb"+ _ → "sieben"+ )+ , (8, const "acht")+ , (9, const "neun")+ , (10, \c → case c of+ CtxMul _ (Lit 3) _ → "ßig"+ CtxMul _ (Lit _) _ → "zig"+ _ → "zehn"+ )+ , (11, const "elf")+ , (12, const "zwölf")+ , (100, const "hundert")+ , (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"+ )+ ]
+ src/Text/Numeral/Language/EN.hs view
@@ -0,0 +1,146 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] en++[@ISO639-2B@] eng++[@ISO639-3@] eng++[@Native name@] English++[@English name@] English+-}++module Text.Numeral.Language.EN+ ( uk_cardinal+ , ukPelletier_cardinal+ , us_cardinal+ , shortScaleStruct+ , longScaleStruct+ , pelletierScaleStruct+ ) 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-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 qualified "numerals-base" Text.Numeral.BigNum as BN ( rule, scaleRepr, pelletierRepr )+++--------------------------------------------------------------------------------+-- EN+--------------------------------------------------------------------------------++uk_cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s+uk_cardinal = render uk_cardinalRepr' ∘ shortScaleStruct++ukPelletier_cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s)+ ⇒ α → Maybe s+ukPelletier_cardinal = render uk_cardinalRepr' { reprScale = pelletierRepr }+ ∘ pelletierScaleStruct+ where+ pelletierRepr = BN.pelletierRepr "illion" "illion"+ "illiard" "illiard"+ []++us_cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s+us_cardinal = render (cardinalRepr (⊞)) ∘ shortScaleStruct+ where+ ((_ `Mul` Lit 10) ⊞ _) _ = "-"+ ((_ `Mul` _ ) ⊞ _) _ = " "+ (_ ⊞ _) _ = ""++shortScaleStruct ∷ ( Integral α, C.Scale α+ , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.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 = pos $ fix $ rule `combine` pelletierScale1 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 R L)+ , ( 100, step1 100 10 R L)+ , (1000, step1 1000 1000 R L)+ ]+ (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 = " "+ (_ ⊞ _) _ = ""++cardinalRepr ∷ (Monoid s, IsString s) ⇒ (Exp → Exp → Ctx Exp → s) → Repr s+cardinalRepr f =+ defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprScale = BN.scaleRepr "illion" "illion" []+ , reprAdd = Just f+ , reprMul = Just (⊞)+ , reprNeg = Just $ \_ _ → "minus "+ }+ where+ (_ ⊞ Lit 10) _ = ""+ (_ ⊞ _ ) _ = " "++ 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 → s+ ten n a m = \c → case c of+ CtxAdd _ (Lit 10) _ → a+ CtxMul _ (Lit 10) _ → m+ _ → n
+ src/Text/Numeral/Language/EO.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] eo++[@ISO639-2B@] epo++[@ISO639-3@] epo++[@Native name@] Esperanto++[@English name@] Esperanto+-}++module Text.Numeral.Language.EO+ ( cardinal+ , struct+ ) 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+++--------------------------------------------------------------------------------+-- EO+--------------------------------------------------------------------------------++cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β+struct = checkPos+ $ fix+ $ findRule ( 0, lit )+ [ ( 11, step 10 10 R L)+ , (100, step 100 10 R L)+ ]+ 1000++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just $ \_ _ _ → " "+ , reprMul = Just $ \_ _ _ → ""+ }+ where+ syms =+ M.fromList+ [ (0, const "nul")+ , (1, const "unu")+ , (2, const "du")+ , (3, const "tri")+ , (4, const "kvar")+ , (5, const "kvin")+ , (6, const "ses")+ , (7, const "sep")+ , (8, const "ok")+ , (9, const "naŭ")+ , (10, const "dek")+ , (100, const "cent")+ , (1000, const "mil")+ ]
+ src/Text/Numeral/Language/ES.hs view
@@ -0,0 +1,167 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] es++[@ISO639-2B@] spa++[@ISO639-3@] spa++[@Native name@] Español++[@English name@] Spanish+-}++module Text.Numeral.Language.ES+ ( cardinal+ , struct+ ) where++-------------------------------------------------------------------------------+-- Imports+-------------------------------------------------------------------------------++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 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+++-------------------------------------------------------------------------------+-- 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++cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ ( Integral α, C.Scale α+ , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β+ )+ ⇒ α → β+struct = pos (fix $ rule `combine` longScale R L BN.rule)+ where+ rule = findRule ( 0, lit )+ [ ( 11, add 10 L )+ , ( 16, 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 = longScaleRepr+ , reprAdd = Just (⊞)+ , reprMul = Just (⊡)+ , reprNeg = Just $ \_ _ → "menos "+ }+ where+ (_ ⊞ Lit 10) _ = ""+ (Lit 10 ⊞ _ ) _ = ""+ (Lit 20 ⊞ _ ) _ = ""+ ((Lit _ `Mul` Lit 10) ⊞ _ ) _ = " y "+ (_ ⊞ _ ) _ = " "++ (_ ⊡ Lit n) _ | n < 1000 = ""+ (_ ⊡ _ ) _ = " "++ syms =+ M.fromList+ [ (0, const "cero")+ , (1, \c → case c of+ CtxAdd _ (Lit 10) _ → "on"+ _ → "uno"+ )+ , (2, \c → case c of+ CtxAdd _ (Lit 10) _ → "do"+ CtxAdd _ (Lit 20) _ → "dós"+ _ → "dos"+ )+ , (3, \c → case c of+ CtxAdd _ (Lit 10) _ → "tre"+ CtxAdd _ (Lit 20) _ → "trés"+ CtxMul _ (Lit 10) _ → "trein"+ _ → "tres"+ )+ , (4, \c → case c of+ CtxAdd _ (Lit 10) _ → "cator"+ CtxMul _ (Lit 10) _ → "cuaren"+ _ → "cuatro"+ )+ , (5, \c → case c of+ CtxAdd _ (Lit 10) _ → "quin"+ CtxMul _ (Lit 10) _ → "cincuen"+ CtxMul _ (Lit 100) _ → "quin"+ _ → "cinco"+ )+ , (6, \c → case c of+ CtxAdd _ (Lit 10) _ → "séis"+ CtxAdd _ (Lit 20) _ → "séis"+ CtxMul _ (Lit 10) _ → "sesen"+ _ → "seis"+ )+ , (7, \c → case c of+ CtxMul _ (Lit 10) _ → "seten"+ CtxMul _ (Lit 100) _ → "sete"+ _ → "siete"+ )+ , (8, \c → case c of+ CtxMul _ (Lit 10) _ → "ochen"+ _ → "ocho"+ )+ , (9, \c → case c of+ CtxMul _ (Lit 10) _ → "noven"+ CtxMul _ (Lit 100) _ → "nove"+ _ → "nueve"+ )+ , (10, \c → case c of+ CtxAdd R (Lit _) _ → "ce"+ CtxAdd L (Lit _) _ → "dieci"+ CtxMul R _ _ → "ta"+ _ → "diez"+ )+ , (20, \c → case c of+ CtxAdd _ (Lit _) _ → "veinti"+ _ → "veinte"+ )+ , (100, \c → case c of+ CtxEmpty → "cien"+ CtxAdd {} → "ciento"+ CtxMul _ (Lit 5) _ → "ientos"+ CtxMul L _ _ → "cien"+ _ → "cientos"+ )+ , (1000, const "mil")+ ]++longScaleRepr ∷ (IsString s, Monoid s)+ ⇒ Integer → Integer → Exp → Ctx Exp → Maybe s+longScaleRepr =+ BN.scaleRepr "illón" "illones"+ [ (4, BN.forms "cuatr" "cuator" "cuator" "cuatra" "cuatri")+ , (9, BN.forms "non" "noven" "noven" "nona" "non")+ ]+
+ src/Text/Numeral/Language/FR.hs view
@@ -0,0 +1,148 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] fr++[@ISO639-2B@] fre++[@ISO639-3@] fra++[@Native name@] Français++[@English name@] French+-}++module Text.Numeral.Language.FR+ ( cardinal+ , struct+ ) 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-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.BigNum as BN+import qualified "numerals-base" Text.Numeral.Exp.Classes as C+++--------------------------------------------------------------------------------+-- FR+--------------------------------------------------------------------------------++{-+Sources:+ http://www.sf.airnet.ne.jp/~ts/language/number/french.html+ http://www.french-linguistics.co.uk/tutorials/numbers/+-}++cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++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)++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 "+ }+ where+ (Lit n ⊞ Lit 10) _ | n ≤ 6 = ""+ (Lit 10 ⊞ Lit n ) _ | n ≥ 7 = "-"+ ((Lit 4 `Mul` Lit 20) ⊞ _ ) _ = "-"+ (_ ⊞ (Lit 1 `Add` Lit 10)) _ = " et "+ (_ ⊞ Lit 1 ) _ = " et "+ ((Lit _ `Mul` Lit 10) ⊞ _ ) _ = "-"+ (Lit 20 ⊞ _ ) _ = "-"+ (_ ⊞ _ ) _ = " "++ (_ ⊡ Lit 10) _ = ""+ (_ ⊡ Lit 20) _ = "-"+ (_ ⊡ _ ) _ = " "++ syms =+ M.fromList+ [ (0, const "zéro")+ , (1, ten "un" "on" "un")+ , (2, ten "deux" "dou" "deux")+ , (3, ten "trois" "trei" "tren")+ , (4, ten "quatre" "quator" "quar")+ , (5, ten "cinq" "quin" "cinqu")+ , (6, ten "six" "sei" "soix")+ , (7, const "sept")+ , (8, const "huit")+ , (9, const "neuf")+ , (10, \c → case c of+ CtxAdd _ (Lit n) _ | n < 7 → "ze"+ | otherwise → "dix"+ CtxMul _ (Lit 3) _ → "te"+ CtxMul R _ _ → "ante"+ _ → "dix"+ )+ , (20, \c → case c of+ CtxMul _ _ CtxEmpty → "vingts"+ _ → "vingt"+ )+ , (100, \c → case c of+ CtxMul R _ CtxEmpty → "cents"+ _ → "cent"+ )+ , (1000, const "mille")+ ]++ ten n a m ctx = case ctx of+ CtxAdd _ (Lit 10) _ → a+ 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"+ )+ ]
+ src/Text/Numeral/Language/GV.hs view
@@ -0,0 +1,108 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] gv++[@ISO639-2@] glv++[@ISO639-3@] glv++[@Native name@] Gaelg++[@English name@] Manx+-}++module Text.Numeral.Language.GV+ ( cardinal+ , struct+ ) 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+++-------------------------------------------------------------------------------+-- 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+-}++cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β+struct = checkPos+ $ fix+ $ findRule ( 1, lit )+ [ ( 11, add 10 L )+ , ( 20, lit )+ , ( 21, add 20 L )+ , ( 40, lit )+ , ( 41, add 40 L )+ , ( 60, mul 20 R L)+ , ( 100, step 100 10 R L)+ , (1000, lit)+ ]+ 1000++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just (⊞)+ , reprMul = Just $ \_ _ _ → " "+ }+ where+ ((Lit _ `Mul` Lit 20) ⊞ Lit 10) _ = " as "+ (_ ⊞ Lit 10) _ = "-"+ (_ ⊞ _ ) _ = " as "++ syms =+ M.fromList+ [ (1, const "nane")+ , (2, \c → case c of+ CtxAdd _ (Lit 10) _ → "daa"+ CtxMul {} → "daa"+ _ → "jees"+ )+ , (3, const "tree")+ , (4, const "kiare")+ , (5, const "queig")+ , (6, const "shey")+ , (7, const "shiaght")+ , (8, const "hoght")+ , (9, const "nuy")+ , (10, \c → case c of+ CtxAdd _ (Lit 2) _ → "yeig"+ CtxAdd _ (Lit _ `Mul` Lit 20) _ → "jeih"+ CtxAdd R _ _ → "jeig"+ _ → "jeih"+ )+ , (20, const "feed")+ , (40, const "daeed")+ , (100, \c → case c of+ CtxMul {} → "cheead"+ _ → "keead"+ )+ , (1000, const "thousane")+ ]
+ src/Text/Numeral/Language/IT.hs view
@@ -0,0 +1,173 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] it++[@ISO639-2B@] ita++[@ISO639-3@] ita++[@Native name@] Italiano++[@English name@] Italian+-}++module Text.Numeral.Language.IT+ ( cardinal+ , struct+ ) 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, (-), Integer )+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )+import "base-unicode-symbols" Data.List.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.BigNum as BN+import qualified "numerals-base" Text.Numeral.Exp.Classes as C+++--------------------------------------------------------------------------------+-- 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++cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ ( Integral α, C.Scale α+ , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.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 "+ }+ where+ (Lit 10 ⊞ Lit 7) _ = "as"+ (Lit 10 ⊞ Lit 9) _ = "an"+ ((_ `Mul` Scale _ _ _) ⊞ _ ) _ = " "+ (_ ⊞ _ ) _ = ""+++ (Lit n ⊡ Lit 10) _ | n ≥ 4 = "an"+ (_ ⊡ Scale _ _ _) _ = " "+ (_ ⊡ _ ) _ = ""++ syms =+ 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"+ )+ , (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"+ )+ , (10, \c → case c of+ CtxAdd _ (Lit _) _ → "dici"+ -- Last vowel removed because of a+ -- phonetic rule:+ CtxMul _ (Lit _) (CtxAdd _ (Lit n) _)+ | n ∈ [1,8] → "t"+ CtxMul R (Lit _) _ → "ta"+ _ → "dieci"+ )+ , (20, \c → case c of+ CtxAdd _ (Lit n) _+ | n ∈ [1,8] → "vent"+ _ → "venti"+ )+ , ( 100+ , let f c = case c of+ 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+ CtxMul {} → "mila"+ _ → "mille"+ )+ ]++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")+ ]
+ src/Text/Numeral/Language/JA.hs view
@@ -0,0 +1,223 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] ja++[@ISO639-2B@] jpn++[@ISO639-3@] jpn++[@Native name@] 日本語++[@English name@] Japanese+-}++module Text.Numeral.Language.JA+ ( struct+ , kanji_cardinal+ , daiji_cardinal+ , on'yomi_cardinal+ , preferred_cardinal+ ) where+++--------------------------------------------------------------------------------+-- Imports+--------------------------------------------------------------------------------++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-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+++--------------------------------------------------------------------------------+-- JA+--------------------------------------------------------------------------------++{-+Sources:+ http://en.wikipedia.org/wiki/Japanese_numerals+ http://www.guidetojapanese.org/numbers.html+-}++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β) ⇒ α → β+struct = pos+ $ fix+ $ findRule ( 0, lit )+ ( [ ( 11, add 10 R )+ , ( 20, mul 10 R L)+ , ( 100, step 100 10 R L)+ , (1000, step 1000 10 R L)+ ]+ ⊕ [ (n, step1 n (dec 4) R L) | n ← map dec [4,8..68] ]+ )+ (dec 72 - 1)+++--------------------------------------------------------------------------------+-- Kanji+--------------------------------------------------------------------------------++kanji_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+kanji_cardinal = kanji_cardinal_repr ∘ struct++kanji_cardinal_repr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+kanji_cardinal_repr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just $ \_ _ _ → ""+ , reprMul = Just $ \_ _ _ → ""+ , reprNeg = Just $ \_ _ → "マイナス"+ }+ where+ syms =+ M.fromList+ [ (0, const "零") -- alternatives:"ゼロ" or "マル"+ , (1, const "一")+ , (2, const "二")+ , (3, const "三")+ , (4, const "四")+ , (5, const "五")+ , (6, const "六")+ , (7, const "七")+ , (8, const "八")+ , (9, const "九")+ , (10, const "十")+ , (100, const "百")+ , (dec 3, const "千")+ , (dec 4, const "万")+ , (dec 8, const "億")+ , (dec 12, const "兆")+ , (dec 16, const "京")+ , (dec 20, const "垓")+ , (dec 24, const "𥝱") -- or 秭?+ , (dec 28, const "穣")+ , (dec 32, const "溝")+ , (dec 36, const "澗")+ , (dec 40, const "正")+ , (dec 44, const "載")+ , (dec 48, const "極")+ , (dec 52, const "恒河沙")+ , (dec 56, const "阿僧祇")+ , (dec 60, const "那由他/那由多")+ , (dec 64, const "不可思議")+ , (dec 68, const "無量大数")+ ]+++--------------------------------------------------------------------------------+-- Daiji+--------------------------------------------------------------------------------++daiji_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+daiji_cardinal = daiji_cardinal_repr ∘ struct++daiji_cardinal_repr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+daiji_cardinal_repr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just $ \_ _ _ → ""+ , reprMul = Just $ \_ _ _ → ""+ , reprNeg = Just $ \_ _ → "マイナス"+ }+ where+ syms =+ M.fromList+ [ (0, const "零") -- alternatives:"ゼロ" or "マル"+ , (1, const "壱")+ , (2, const "弐")+ , (3, const "参")+ , (4, const "四")+ , (5, const "五")+ , (6, const "六")+ , (7, const "七")+ , (8, const "八")+ , (9, const "九")+ , (10, const "拾")+ , (100, const "百")+ , (dec 3, const "千")+ , (dec 4, const "万")+ ]+++--------------------------------------------------------------------------------+-- Generic reading+--------------------------------------------------------------------------------++generic_repr ∷ (Monoid s, IsString s) ⇒ s → s → Repr s+generic_repr four seven = defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just $ \_ _ _ → " "+ , reprMul = Just $ \_ _ _ → ""+ , reprNeg = Just $ \_ _ → "mainasu "+ }+ where+ syms =+ M.fromList+ [ (0, const "rei")+ , (1, const "ichi")+ , (2, const "ni")+ , (3, const "san")+ , (4, const four)+ , (5, const "go")+ , (6, const "roku")+ , (7, const seven)+ , (8, const "hachi")+ , (9, const "kyū")+ , (10, const "jū")+ , (100, \c → case c of+ (CtxMul _ (Lit 3) _) → "byaku" -- rendaku+ _ → "hyaku"+ )+ , (dec 3, const "sen")+ , (dec 4, const "man")+ , (dec 8, const "oku")+ , (dec 12, const "chō")+ , (dec 16, const "kei")+ , (dec 20, const "gai")+ , (dec 24, const "jo")+ , (dec 28, const "jō")+ , (dec 32, const "kō")+ , (dec 36, const "kan")+ , (dec 40, const "sei")+ , (dec 44, const "sai")+ , (dec 48, const "goku")+ , (dec 52, const "gōgasha")+ , (dec 56, const "asōgi")+ , (dec 60, const "nayuta")+ , (dec 64, const "fukashigi")+ , (dec 68, const "muryōtaisū")+ ]+++--------------------------------------------------------------------------------+-- On'yomi+--------------------------------------------------------------------------------++on'yomi_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+on'yomi_cardinal = on'yomi_cardinal_repr ∘ struct++on'yomi_cardinal_repr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+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_cardinal_repr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+preferred_cardinal_repr = render $ generic_repr "yon" "nana"
+ src/Text/Numeral/Language/LA.hs view
@@ -0,0 +1,158 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] la++[@ISO639-2B@] lat++[@ISO639-3@] lat++[@Native name@] Latine++[@English name@] Latin+-}++module Text.Numeral.Language.LA+ ( cardinal+ , struct+ ) where+++--------------------------------------------------------------------------------+-- Imports+--------------------------------------------------------------------------------++import "base" Data.Bool ( otherwise )+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+++--------------------------------------------------------------------------------+-- LA+--------------------------------------------------------------------------------++{-+Sources:+ http://www.informalmusic.com/latinsoc/latnum.html+ http://www.sf.airnet.ne.jp/~ts/language/number/latin.html+-}++cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Sub β, C.Mul β) ⇒ α → β+struct = checkPos+ $ fix+ $ findRule ( 0, lit)+ ( [ (11, add 10 L)+ , (18, sub 20)+ ]+ ⊕ concat [ [ (n, mul 10 R L)+ , (n+8, sub $ n+10)+ ]+ | n ← [20,30..90]+ ]+ ⊕ [ ( 100, step 100 10 R L)+ , (1000, lit)+ ]+ )+ 1000++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just (⊞)+ , reprMul = Just (⊡)+ , reprSub = Just $ \_ _ _ → "dē"+ , reprNeg = Just $ \_ _ → "minus "+ }+ where+ ((_ `Mul` Lit _) ⊞ _) _ = " "+ (_ ⊞ _) _ = ""++ (_ ⊡ Lit n) _ | n ≤ 100 = ""+ (_ ⊡ _ ) _ = " "++ syms =+ M.fromList+ [ (0, const "nihil")+ , (1, \c → case c of+ CtxAdd _ (Lit 10) _ → "ūn"+ CtxSub _ _ _ → "ūn"+ _ → "ūnus"+ )+ , (2, \c → case c of+ CtxMul _ (Lit 10) _ → "vī"+ CtxMul _ (Lit 100) _ → "du"+ _ → "duo"+ )+ , (3, \c → case c of+ CtxAdd _ (Lit 10) _ → "trē"+ CtxMul _ (Lit 10) _ → "trī"+ CtxMul _ (Lit 100) _ → "tre"+ _ → "trēs"+ )+ , (4, \c → case c of+ CtxMul _ (Lit 10) _ → "quadrā"+ CtxMul _ (Lit 100) _ → "quadrin"+ _ → "quattuor"+ )+ , (5, \c → case c of+ CtxAdd _ (Lit 10) _ → "quīn"+ CtxMul _ (Lit 10) _ → "quīnquā"+ CtxMul _ (Lit 100) _ → "quīn"+ _ → "quīnque"+ )+ , (6, \c → case c of+ CtxAdd _ (Lit 10) _ → "sē"+ CtxMul _ (Lit 10) _ → "sexā"+ CtxMul _ (Lit 100) _ → "ses"+ _ → "sex"+ )+ , (7, \c → case c of+ CtxAdd _ (Lit 10) _ → "septen"+ CtxMul _ (Lit 10) _ → "septuā"+ CtxMul _ (Lit 100) _ → "septin"+ _ → "septem"+ )+ , (8, \c → case c of+ CtxMul _ (Lit 100) _ → "octin"+ _ → "octō"+ )+ , (9, \c → case c of+ CtxMul _ (Lit 10) _ → "nōnā"+ CtxMul _ (Lit 100) _ → "nōn"+ _ → "novem"+ )+ , (10, \c → case c of+ CtxAdd {} → "decim"+ CtxMul _ (Lit 2) _ → "gintī"+ CtxMul {} → "gintā"+ _ → "decem"+ )+ , (100, \c → case c of+ CtxMul _ (Lit n) _+ | n ∈ [2,3,6] → "centī"+ | otherwise → "gentī"+ _ → "centum"+ )+ , (1000, \c → case c of+ CtxMul {} → "milia"+ _ → "mīlle"+ )+ ]
+ src/Text/Numeral/Language/MG.hs view
@@ -0,0 +1,111 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] mg++[@ISO639-2@] mlg++[@ISO639-3@] mlg++[@Native name@] -++[@English name@] Malagasy+-}++module Text.Numeral.Language.MG+ ( cardinal+ , struct+ ) where+++-------------------------------------------------------------------------------+-- Imports+-------------------------------------------------------------------------------++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+++-------------------------------------------------------------------------------+-- MG+-------------------------------------------------------------------------------++{-+Sources:+ http://en.wikipedia.org/wiki/Malagasy_language+ http://www.sf.airnet.ne.jp/~ts/language/number/malagasy.html+-}++cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.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+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just (⊞)+ , reprMul = Just (⊡)+ }+ where+ (_ ⊞ Lit 10 ) _ = " ambin'ny "+ (_ ⊞ (Lit _ `Mul` Lit 10)) _ = " amby "+ (_ ⊞ _ ) _ = " sy "++ (_ ⊡ Lit 10 ) _ = ""+ (_ ⊡ Lit 100) _ = ""+ (_ ⊡ _ ) _ = " "++ syms =+ M.fromList+ [ (0, const "haotra")+ , (1, \c → case c of+ CtxAdd {} → "iraika"+ _ → "iray"+ )+ , (2, mulForms "roa" "roa" "roan")+ , (3, mulForms "telo" "telo" "telon")+ , (4, mulForms "efatra" "efa" "efa" )+ , (5, mulForms "dimy" "dimam" "diman")+ , (6, mulForms "enina" "enim" "enin" )+ , (7, mulForms "fito" "fito" "fiton")+ , (8, mulForms "valo" "valo" "valon")+ , (9, mulForms "sivy" "sivi" "sivin")+ , (10, \c → case c of+ CtxMul _ (Lit n) _+ | n < 9 → "polo"+ _ → "folo"+ )+ , (100, \c → case c of+ CtxMul {} → "jato"+ _ → "zato"+ )+ , (1000, const "arivo")+ , (dec 4, const "alina")+ , (dec 5, const "hetsy")+ , (dec 6, const "tapitrisa")+ ]++ mulForms o t h = \c → case c of+ CtxMul _ (Lit 10) _ → t+ CtxMul _ (Lit 100) _ → h+ _ → o
+ src/Text/Numeral/Language/NL.hs view
@@ -0,0 +1,112 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] nl++[@ISO639-2B@] dut++[@ISO639-3@] nld++[@Native name@] Nederlands++[@English name@] Dutch+-}++module Text.Numeral.Language.NL+ ( cardinal+ , struct+ ) 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, (-) )+import "base-unicode-symbols" Data.Function.Unicode ( (∘) )+import "base-unicode-symbols" Data.List.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 )+++--------------------------------------------------------------------------------+-- NL+--------------------------------------------------------------------------------++cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ ( Integral α, C.Scale α+ , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β+ )+ ⇒ α → β+struct = pos $ fix $ rule `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)++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 (⊞)+ , reprMul = Just $ \_ _ _ → ""+ , reprNeg = Just $ \_ _ → "min "+ }+ where+ (_ ⊞ Lit 10) _ = ""+ (Lit n ⊞ _) _ | n ∈ [2,3] = "ën"+ | n < 10 = "en"+ | otherwise = ""+ (_ ⊞ _) _ = ""++ syms =+ 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")+ , (8, \c → case c of+ CtxMul _ (Lit 10) _ → "tach"+ CtxAdd _ (Lit _) _ → "ach"+ _ → "acht"+ )+ , (9, const "negen")+ , (10, \c → case c of+ CtxMul R _ _ → "tig"+ _ → "tien"+ )+ , (11, const "elf")+ , (12, const "twaalf")+ , (100, const "honderd")+ , (1000, const "duizend")+ ]++ tenForms n t ctx = case ctx of+ CtxMul _ (Lit 10) _ → t+ CtxAdd _ (Lit _) _ → t+ _ → n
+ src/Text/Numeral/Language/NO.hs view
@@ -0,0 +1,96 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] nb++[@ISO639-2B@] nob++[@ISO639-3@] nob++[@Native name@] Bokmål++[@English name@] Norwegian Bokmål+-}++module Text.Numeral.Language.NO+ ( cardinal+ , struct+ ) 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+++-------------------------------------------------------------------------------+-- NO+-------------------------------------------------------------------------------++-- Sources:+-- http://en.wikibooks.org/wiki/Norwegian_Numbers+-- http://www.sf.airnet.ne.jp/~ts/language/number/norwegian.html++cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β) ⇒ α → β+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)+ ]+ 1000++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just $ \_ _ _ → ""+ , reprMul = Just $ \_ _ _ → ""+ , reprNeg = Just $ \_ _ → "minus "+ }+ where+ syms =+ M.fromList+ [ (0, const "null")+ , (1, const "en")+ , (2, const "to")+ , (3, ten "tre" "tret" "tret")+ , (4, ten "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")+ , (10, \c → case c of+ CtxAdd {} → "ten"+ _ → "ti"+ )+ , (11, const "elleve")+ , (12, const "tolv")+ , (20, const "tjue")+ , (100, const "hundre")+ , (1000, const "tusen")+ ]++ ten n a m = \c → case c of+ CtxAdd _ (Lit 10) _ → a+ CtxMul {} → m+ _ → n
+ src/Text/Numeral/Language/NQM.hs view
@@ -0,0 +1,81 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] -++[@ISO639-2B@] -++[@ISO639-3@] nqm++[@Native name@] -++[@English name@] Ndom+-}++module Text.Numeral.Language.NQM+ ( cardinal+ , struct+ ) 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+++--------------------------------------------------------------------------------+-- NQM+--------------------------------------------------------------------------------++cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β+struct = checkPos+ $ fix+ $ findRule ( 1, lit )+ [ ( 7, add 6 R )+ , ( 12, mul 6 R R)+ , ( 18, lit )+ , ( 19, add 18 R )+ , ( 36, lit )+ , ( 37, add 36 R )+ , ( 72, mul 36 R R)+ ]+ 107++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just $ \_ _ _ → " abo "+ , reprMul = Just (⊡)+ }+ where+ (Lit 36 ⊡ _) _ = " "+ (_ ⊡ _) _ = " an "++ syms =+ M.fromList+ [ ( 1, const "sas")+ , ( 2, const "thef")+ , ( 3, const "ithin")+ , ( 4, const "thonith")+ , ( 5, const "meregh")+ , ( 6, const "mer")+ , (18, const "tondor")+ , (36, const "nif")+ ]
+ src/Text/Numeral/Language/OJ.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] oj++[@ISO639-2@] oji++[@ISO639-3@] oji++[@Native name@] ᐊᓂᔑᓈᐯᒧᐎᓐ (Anishinaabemowin)++[@English name@] Ojibwe+-}++module Text.Numeral.Language.OJ+ ( cardinal+ , struct+ ) 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+++--------------------------------------------------------------------------------+-- OJ+--------------------------------------------------------------------------------++{-+Sources:+ http://www.sf.airnet.ne.jp/~ts/language/number/ojibwa.html+ http://www.languagesandnumbers.com/how-to-count-in-ojibwa/en/oji/+-}++cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β)+ ⇒ α → β+struct = checkPos+ $ fix+ $ findRule ( 1, lit )+ [ ( 11, step 10 10 R L)+ , ( 100, step 100 10 R L)+ , (1000, step 1000 2 R L)+ ]+ 1999++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just $ \_ _ _ → " shaa "+ , reprMul = Just $ \_ _ _ → ""+ }+ where+ syms =+ M.fromList+ [ (0, const "kaagego" )+ , (1, const "bezhik" )+ , (2, const "niizh" )+ , (3, forms "nswi" "nsim" "ns" )+ , (4, forms "niiwin" "niim" "nii" )+ , (5, forms "naanan" "naanmi" "naan" )+ , (6, forms "ngodwaaswi" "ngodwaasmi" "ngodwaas" )+ , (7, forms "niizhwaaswi" "niizhwaasmi" "niizhwaas")+ , (8, forms "nshwaaswi" "nshwaasmi" "nshwaas" )+ , (9, forms "zhaangswi" "zhaangsmi" "zhaangs" )+ , (10, \c → case c of+ CtxMul {} → "taana"+ _ → "mdaaswi"+ )+ , (100, \c → case c of+ CtxMul {} → "waak"+ _ → "ngodwaak"+ )+ , (1000, const "mdaaswaak")+ ]++ forms ∷ s → s → s → Ctx Exp → s+ forms o t h = \c → case c of+ CtxMul _ (Lit 10) _ → t+ CtxMul _ (Lit 100) _ → h+ _ → o
+ src/Text/Numeral/Language/PT.hs view
@@ -0,0 +1,159 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] pt++[@ISO639-2@] por++[@ISO639-3@] por++[@Native name@] Português++[@English name@] Portuguese+-}++module Text.Numeral.Language.PT+ ( cardinal+ , struct+ ) 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-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.BigNum as BN+import qualified "numerals-base" Text.Numeral.Exp.Classes as C+++-------------------------------------------------------------------------------+-- PT+-------------------------------------------------------------------------------++-- Sources:+-- http://www.sonia-portuguese.com/text/numerals.htm+-- http://www.smartphrase.com/Portuguese/po_numbers_voc.shtml++cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ ( Integral α, C.Scale α+ , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β+ )+ ⇒ α → β+struct = pos $ fix $ rule `combine` shortScale R L BN.rule+ where+ rule = findRule ( 0, lit )+ [ ( 11, add 10 L )+ , ( 16, add 10 R )+ , ( 20, 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 = shortScaleRepr+ , reprAdd = Just (⊞)+ , reprMul = Just (⊡)+ , reprNeg = Just $ \_ _ → "menos "+ }+ where+ (Lit 10 ⊞ Lit n ) _ | n < 8 = "as"+ | n ≡ 8 = ""+ | otherwise = "a"+ (Lit _ ⊞ Lit 10) _ = ""+ (_ ⊞ _ ) _ = " e "+++ (_ ⊡ Lit 10 ) _ = ""+ (_ ⊡ Lit 100) _ = ""+ (_ ⊡ _ ) _ = " "++ syms =+ M.fromList+ [ (0, const "zero")+ , (1, \c → case c of+ CtxAdd _ (Lit 10) _ → "on"+ _ → "um"+ )+ , (2, \c → case c of+ CtxAdd _ (Lit 10) _ → "do"+ CtxMul _ (Lit 10) _ → "vin"+ CtxMul _ (Lit 100) _ → "duz"+ _ → "dois"+ )+ , (3, \c → case c of+ CtxAdd _ (Lit 10) _ → "tre"+ CtxMul _ (Lit 10) _ → "trin"+ CtxMul _ (Lit 100) _ → "trez"+ _ → "três"+ )+ , (4, \c → case c of+ CtxAdd _ (Lit 10) _ → "cator"+ CtxMul _ (Lit 10) _ → "quaren"+ _ → "quatro"+ )+ , (5, \c → case c of+ CtxAdd _ (Lit 10) _ → "quin"+ CtxMul _ (Lit 10) _ → "cinquen"+ CtxMul _ (Lit 100) _ → "quin"+ _ → "cinco"+ )+ , (6, \c → case c of+ CtxMul _ (Lit 10) _ → "sessen"+ _ → "seis"+ )+ , (7, \c → case c of+ CtxMul _ (Lit 10) _ → "seten"+ _ → "sete"+ )+ , (8, \c → case c of+ CtxMul _ (Lit 10) _ → "oiten"+ _ → "oito"+ )+ , (9, \c → case c of+ CtxMul _ (Lit 10) _ → "noven"+ _ → "nove"+ )+ , (10, \c → case c of+ CtxAdd R (Lit _) _ → "ze"+ CtxMul R (Lit 2) _ → "te"+ CtxMul R (Lit _) _ → "ta"+ _ → "dez"+ )+ , (100, \c → case c of+ CtxAdd {} → "cento"+ CtxMul _ (Lit n) _+ | n ≤ 3 → "entos"+ | n ≡ 4 → "centos"+ | n ≡ 5 → "hentos"+ | otherwise → "centos"+ _ → "cem"+ )+ , (1000, const "mil")+ ]++shortScaleRepr ∷ (IsString s, Monoid s)+ ⇒ Integer → Integer → Exp → Ctx Exp → Maybe s+shortScaleRepr =+ BN.scaleRepr "ilhão" "ilhões"+ [(4, BN.forms "quatr" "quator" "quator" "quatra" "quatri")]
+ src/Text/Numeral/Language/RU.hs view
@@ -0,0 +1,155 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] ru++[@ISO639-2@] rus++[@ISO639-3@] rus++[@Native name@] Русский язык++[@English name@] Russian+-}++module Text.Numeral.Language.RU+ ( cardinal+ , struct+ ) where+++--------------------------------------------------------------------------------+-- Imports+--------------------------------------------------------------------------------++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-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+++--------------------------------------------------------------------------------+-- 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+-}++cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β) ⇒ α → β+struct = pos + $ fix + $ findRule ( 0, lit )+ [ ( 11, add 10 L )+ , ( 20, mul 10 R L )+ , ( 40, lit )+ , ( 41, add 40 R )+ , ( 50, 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+ , reprAdd = Just (⊞)+ , reprMul = Just (⊡)+ , reprNeg = Just $ \_ _ → "минус "+ }+ where+ (Lit n ⊞ Lit 10) _ | n < 10 = "на"+ (_ ⊞ _ ) _ = " "++ (_ ⊡ Lit n) _ | n ≤ 100 = ""+ (_ ⊡ _ ) _ = " "++ syms =+ M.fromList+ [ (0, const "ноль")+ , (1, \c → case c of+ CtxAdd _ (Lit 40) (CtxMul {}) → "одна"+ CtxAdd _ (_ `Mul` _) (CtxMul {}) → "одна"+ _ → "один"+ )+ , (2, \c → case c of+ CtxAdd _ (Lit 10) _ → "две"+ CtxAdd _ (Lit 40) (CtxMul {}) → "две"+ CtxAdd _ (_ `Mul` _) (CtxMul {}) → "две"+ CtxMul _ (Lit n) _ | n > 10 → "две"+ _ → "два"+ )+ , (3, const "три")+ , (4, \c → case c of+ CtxAdd _ (Lit 10) _ → "четыр"+ _ → "четыре"+ )+ , (5, \c → case c of+ CtxAdd _ (Lit 10) _ → "пят"+ _ → "пять"+ )+ , (6, \c → case c of+ CtxAdd _ (Lit 10) _ → "шест"+ _ → "шесть"+ )+ , (7, \c → case c of+ CtxAdd _ (Lit 10) _ → "сем"+ _ → "семь"+ )+ , (8, \c → case c of+ CtxAdd _ (Lit 10) _ → "восем"+ _ → "восемь"+ )+ , (9, \c → case c of+ CtxAdd _ (Lit 10) _ → "девят"+ CtxMul _ (Lit 10) _ → "девя"+ _ → "девять"+ )+ , (10, \c → case c of+ CtxAdd _ (Lit n) _ | n ≤ 9 → "дцать"+ CtxMul _ (Lit n) _ | n < 4 → "дцать"+ | n < 9 → "десят"+ | n ≡ 9 → "носто"+ _ → "десять"+ )+ , (40, const "сорок")+ , (100, \c → case c of+ CtxMul _ (Lit n) _ | n ≡ 2 → "сти"+ | n ≤ 4 → "ста"+ | n ≤ 9 → "сот"+ _ → "сто"+ )+ , (1000, \c → case c of+ CtxMul _ (Lit 40 `Add` Lit n) _ | n ≡ 1 → "тысяча"+ | n ≤ 4 → "тысячи"+ | n ≥ 5 → "тысяч"+ CtxMul _ (_ `Mul` _ `Add` Lit n) _ | n ≡ 1 → "тысяча"+ | n ≤ 4 → "тысячи"+ | n ≥ 5 → "тысяч"+ CtxMul _ (Lit n) _ | n ≤ 4 → "тысячи"+ CtxMul {} → "тысяч"+ _ → "тысяча"+ )+ , (dec 6, const "миллион")+ , (dec 9, const "миллиард")+ ]
+ src/Text/Numeral/Language/SCO.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] -++[@ISO639-2@] sco++[@ISO639-3@] sco++[@Native name@] Scots++[@English name@] Scots+-}++module Text.Numeral.Language.SCO+ ( cardinal+ , struct+ ) 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+++-------------------------------------------------------------------------------+-- SCO+-------------------------------------------------------------------------------++{-+Sources:+ http://www.sf.airnet.ne.jp/~ts/language/number/scots.html+-}++cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β+struct = checkPos+ $ fix+ $ findRule ( 1, lit )+ [ ( 13, add 10 L )+ , ( 20, mul 10 R L)+ , (100, lit )+ ]+ 100++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just (⊞)+ , reprMul = Just $ \_ _ _ → ""+ }+ where+ ((_ `Mul` _) ⊞ _) _ = " "+ (_ ⊞ _) _ = ""++ syms =+ M.fromList+ [ (1, const "ane" )+ , (2, tenForms "twa" "twa" "twin" )+ , (3, tenForms "three" "ther" "ther" )+ , (4, const "fower" )+ , (5, tenForms "five" "feif" "fuf" )+ , (6, const "sax" )+ , (7, tenForms "seeven" "seiven" "seeven")+ , (8, tenForms "echt" "ech" "ech" )+ , (9, tenForms "nine" "nin" "nin" )+ , (10, \c → case c of+ CtxAdd {} → "teen"+ CtxMul {} → "tie"+ _ → "ten"+ )+ , (11, const "aleeven")+ , (12, const "twal")+ , (100, const "hunner")+ , (1000, const "thousant")+ ]++ tenForms o a m = \c → case c of+ CtxAdd L _ _ → a+ CtxMul {} → m+ _ → o
+ src/Text/Numeral/Language/SV.hs view
@@ -0,0 +1,111 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] sv++[@ISO639-2B@] swe++[@ISO639-3@] swe++[@Native name@] svenska++[@English name@] Swedish+-}++module Text.Numeral.Language.SV+ ( cardinal+ , struct+ ) 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, (-), Integer )+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+++-------------------------------------------------------------------------------+-- SV+-------------------------------------------------------------------------------++cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ ( Integral α, C.Scale α+ , C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β, C.Scale β+ )+ ⇒ α → β+struct = pos $ fix $ rule `combine` pelletierScale R L BN.rule+ 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)+ ]+ (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 $ \_ _ → "minus "+ }+ where+ syms =+ 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")+ , (10, \c → case c of+ CtxAdd {} → "ton"+ _ → "tio"+ )+ , (11, const "elva")+ , (12, const "tolv")+ , (20, const "tjugo")+ , (100, const "hundra")+ , (1000, const "tusen")+ ]++ ten n a m = \c → case c of+ CtxAdd _ (Lit 10) _ → a+ CtxMul _ (Lit 10) _ → m+ _ → n++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")+ ]
+ src/Text/Numeral/Language/TR.hs view
@@ -0,0 +1,156 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] tr++[@ISO639-2@] tur++[@ISO639-3@] tur++[@Native name@] Türkçe++[@English name@] Turkish+-}++module Text.Numeral.Language.TR+ ( cardinal+ , struct+ ) 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.String ( IsString )+import "base" Prelude ( Integral, (-), divMod, Integer )+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 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 )+++--------------------------------------------------------------------------------+-- 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+-}++cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Scale α, C.Unknown β, C.Lit β, C.Add β, C.Mul β, C.Scale β)+ ⇒ α → β+struct = checkPos $ fix $ rule `combine` shortScale1 R L BN.rule++rule ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ Rule α β+rule = findRule ( 0, lit )+ [ ( 11, addToTens )+ , ( 100, step 100 10 R L)+ , (1000, step 1000 1000 R L)+ ]+ (dec 6 - 1)++addToTens ∷ (Integral α, C.Lit β, C.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++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprScale = scaleRepr+ , reprAdd = Just (⊞)+ , reprMul = Just $ \_ _ _ → " "+ }+ where+ (Lit 10 ⊞ _) (CtxMul {}) = ""+ (_ ⊞ _) _ = " "++ syms =+ M.fromList+ [ (0, const "sıfır")+ , (1, const "bir")+ , (2, const "iki")+ , (3, \c → case c of+ CtxEmpty → "üç"+ _ → "uç"+ )+ , (4, const "dört")+ , (5, const "beş")+ , (6, const "altı")+ , (7, const "yedi")+ , (8, const "sekiz")+ , (9, const "dokuz")+ , (10, const "on")+ , (20, const "yirmi")+ , (30, const "otuz")+ , (40, const "kırk")+ , (50, const "elli")+ , (60, const "altmış")+ , (70, const "yetmiş")+ , (80, const "seksen")+ , (90, const "doksan")+ , (100, const "yüz")+ , (1000, const "bin")+ ]++scaleRepr ∷ (IsString s, Monoid s)+ ⇒ Integer → Integer → Exp → Ctx Exp → Maybe s+scaleRepr = BN.scaleRepr+ "ilyon" "ilyon"+ [ (1, BN.forms "m" "an" "an" "" "")+ , (2, BN.forms "b" "do" "do" "vi" "du")+ , (3, \c → case c of+ CtxAdd _ (Lit 10) _ → "tre"+ CtxAdd _ (Lit 100) _ → "tre"+ CtxAdd {} → "tres"+ CtxMul _ (Lit 100) _ → "tre"+ CtxMul {} → "tri"+ _ → "tr"+ )+ , (4, BN.forms "katr" "kator" "kator" "katra" "katrin")+ , (5, BN.forms "kent" "ken" "kenka" "kenka" "ken")+ , (6, BN.forms "sekst" "seks" "ses" "seksa" "se")+ , (7, BN.forms "sept" "septen" "septem" "septe" "septin")+ , (8, BN.forms "okt" "okto" "okto" "okto" "oktin")+ , (10, \c → case c of+ CtxAdd _ (Lit 100) _ → "desi"+ CtxAdd _ (Lit 1) (CtxAdd {}) → "desi"+ CtxMul _ (Lit n) (CtxAdd L (Lit 100) _)+ | n ≡ 2 → "ginti"+ | otherwise → "ginta"+ CtxMul _ (Lit _) (CtxAdd _ _ CtxEmpty) → "gint"+ CtxMul _ (Lit _) CtxEmpty → "gint"+ CtxMul {} → "ginti"+ _ → "des"+ )+ , (100, \c → case c of+ CtxMul _ (Lit n) _ | n ∉ [2,3,6] → "gent"+ _ → "sent"+ )+ ]
+ src/Text/Numeral/Language/WO.hs view
@@ -0,0 +1,99 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] wo++[@ISO639-2@] wo1++[@ISO639-3@] wo1++[@Native name@] Wolof++[@English name@] Wolof+-}++module Text.Numeral.Language.WO+ ( cardinal+ , struct+ ) 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+++--------------------------------------------------------------------------------+-- WO+--------------------------------------------------------------------------------++cardinal ∷ (Integral α, C.Scale α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Mul β) ⇒ α → β+struct = checkPos+ $ fix+ $ findRule ( 0, lit )+ [ ( 6, add 5 R )+ , ( 10, lit )+ , ( 11, add 10 R )+ , ( 20, mul 10 R L )+ , (100, step 100 10 R L)+ , (1000, step 1000 1000 R L)+ , (dec 6, lit)+ ]+ (dec 6)++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just (⊞)+ , reprMul = Just (⊡)+ }+ where+ (Lit 5 ⊞ _) _ = "-"+ (_ ⊞ _) _ = " ak "++ (_ ⊡ Lit 10) _ = "-"+ (_ ⊡ _ ) _ = " "++ syms =+ M.fromList+ [ (0, const "tus")+ , (1, i "benn")+ , (2, i "ñaar")+ , (3, i "ñett")+ , (4, i "ñeent")+ , (5, i "juróom")+ , (10, i "fukk")+ , (100, i "téeméer")+ , (1000, const "junni")+ , (dec 6, const "tamndareet")+ ]++ i s = \c → s ⊕ case c of+ CtxMul _ (Lit n) _ | n ≥ 100 → "i"+ CtxAdd R _ (CtxMul _ (Lit n) _) | n ≥ 100 → "i"+ _ → ""
+ src/Text/Numeral/Language/YOR.hs view
@@ -0,0 +1,149 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] yo++[@ISO639-2@] yor++[@ISO639-3@] yor++[@Native name@] èdè Yorùbá++[@English name@] Yoruba+-}++module Text.Numeral.Language.YOR+ ( cardinal+ , struct+ ) 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.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+++--------------------------------------------------------------------------------+-- YOR+--------------------------------------------------------------------------------++{-+TODO: multiple sources make me suspect that this definition is not correct++It may also be the case that numbers have multiple possible deriviations.++ 45 = (20*3) - 10 - 5+ 50 = (20*3) - 10+108 = (20*6) - 10 - 2+300 = 20 * (20 - 5)+318 = 400 - (20*4) - 2+525 = (200*3) - (20*4) + 5+-}++cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+cardinal = cardinalRepr ∘ struct++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Add β, C.Sub β, C.Mul β) ⇒ α → β+struct = checkPos+ $ fix+ $ conditional (≡ -5) lit+ $ findRule ( 1, lit )+ [ ( 11, add 10 L )+ , ( 15, add 20 L )+ , ( 16, sub 20 )+ , ( 20, lit )+ , ( 21, add 20 L )+ , ( 25, add 30 L )+ , ( 26, sub 30 )+ , ( 30, lit )+ , ( 31, add 30 L )+ , ( 35, sub 40 )+ , ( 40, mul 20 L R)+ , ( 45, sub 50 )+ , ( 50, lit )+ , ( 51, add 50 L )+ , ( 55, sub 60 )+ , ( 60, mul 20 L R)+ , ( 65, sub 70 )+ , ( 70, lit )+ , ( 71, add 70 L )+ , ( 75, sub 80 )+ , ( 80, mul 20 L R)+ , ( 85, sub 90 )+ , ( 90, lit )+ , ( 91, add 90 L )+ , ( 95, sub 100 )+ , ( 100, mul 20 L R)+ , ( 200, mul 100 L R)+ , (1000, lit )+ ]+ 1000++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+cardinalRepr = render defaultRepr+ { reprValue = \n → M.lookup n syms+ , reprAdd = Just (⊞)+ , reprMul = Just (⊡)+ , reprSub = Just $ \_ _ _ → "dil"+ }+ where+ (_ ⊞ Lit 10) _ = ""+ (Lit n ⊞ _) _ | n ≡ -5 = ""+ | otherwise = "lel"+ (_ ⊞ _) _ = ""++ ((Lit 20 `Mul` Lit 5) ⊡ _) _ = " "+ (_ ⊡ _) _ = ""++ syms =+ M.fromList+ [ (-5, const "med")+ , ( 1, \c → case c of+ CtxAdd {} → "mokan"+ CtxSub {} → "mokan"+ _ → "ikan"+ )+ , ( 2, twentyForm "me" "go" "ji")+ , ( 3, twentyForm "me" "go" "ta")+ , ( 4, twentyForm "me" "go" "rin")+ , ( 5, twentyForm "ma" "go" "run")+ , ( 6, const $ "me" ⊕ "fa")+ , ( 7, const $ "me" ⊕ "je")+ , ( 8, const $ "me" ⊕ "jo")+ , ( 9, const $ "me" ⊕ "san")+ , (10, \c → case c of+ CtxAdd {} → "la"+ _ → "mewa"+ )+ , (20, \c → case c of+ CtxMul {} → "o"+ _ → "ogun"+ )+ , (30, const "ogbon")+ , (50, const "adota")+ , (70, const "adorin")+ , (90, const "adorun")+ , (1000, const "egberun")+ ]++ twentyForm c m s = \ctx → case ctx of+ CtxMul _ (Lit 20) _ → m+ _ → c+ ⊕ s
+ src/Text/Numeral/Language/ZH.hs view
@@ -0,0 +1,290 @@+{-# LANGUAGE NoImplicitPrelude+ , OverloadedStrings+ , PackageImports+ , UnicodeSyntax+ #-}++{-|+[@ISO639-1@] zh++[@ISO639-2B@] chi++[@ISO639-2T@] zho++[@ISO639-3@] cmn++[@Native name@] 官話++[@English name@] Chinese+-}++module Text.Numeral.Language.ZH+ ( struct+ , trad_cardinal+ , simpl_cardinal+ , finance_trad_cardinal+ , finance_simpl_cardinal+ , pinyin_cardinal+ ) where+++--------------------------------------------------------------------------------+-- Imports+--------------------------------------------------------------------------------++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-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+++--------------------------------------------------------------------------------+-- ZH+--------------------------------------------------------------------------------++{-+Sources:+ http://www.sf.airnet.ne.jp/~ts/language/number/mandarin.html+-}++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+ | otherwise = f n++mulX ∷ (Integral α, C.Lit β, C.Add β, C.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)+ in if a ≡ 0+ then mval+ else (flipIfR aSide C.add) (add0 val f a) mval+ where+ (⊡) = flipIfR mSide C.mul++struct ∷ (Integral α, C.Unknown β, C.Lit β, C.Neg β, C.Add β, C.Mul β) ⇒ α → β+struct = pos+ $ fix+ $ findRule (0, lit)+ ( [(dec 1, step (dec 1) (dec 1) R L)]+ ⊕ [(dec n, stepX (dec n) (dec 1) R L) | n ← [2,3]]+ ⊕ [(dec n, stepX (dec n) (dec 4) R L) | n ← [4,8..44]]+ )+ (dec 48 - 1)+ where+ stepX = mkStep lit1 addX mulX++ addX val _ = \f n → C.add (f val) (add0 val f $ n - val)++cardinalRepr ∷ (Monoid s, IsString s) ⇒ Repr s+cardinalRepr = defaultRepr+ { reprAdd = Just $ \_ _ _ → ""+ , reprMul = Just $ \_ _ _ → ""+ }+++--------------------------------------------------------------------------------+-- Traditional Characters+--------------------------------------------------------------------------------++trad_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+trad_cardinal = trad_cardinalRepr ∘ struct++trad_cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+trad_cardinalRepr =+ render cardinalRepr+ { reprValue = \n → M.lookup n trad_syms+ , reprNeg = Just $ \_ _ → "負"+ }++trad_syms ∷ (Integral α, IsString s) ⇒ M.Map α (Ctx Exp → s)+trad_syms =+ M.fromList+ [ (0, \c → case c of+ CtxEmpty → "零"+ _ → "〇"+ )+ , (1, const "一")+ , (2, \c → case c of+ CtxMul _ (Lit n) _ | n ≥ 1000 → "兩"+ _ → "二"+ )+ , (3, const "三")+ , (4, const "四")+ , (5, const "五")+ , (6, const "六")+ , (7, const "七")+ , (8, const "八")+ , (9, const "九")+ , (10, const "十")+ , (100, const "百")+ , (1000, const "千")+ , (dec 4, const "萬")+ , (dec 8, const "億")+ , (dec 12, const "兆")+ , (dec 16, const "京")+ , (dec 20, const "垓")+ , (dec 24, const "秭")+ , (dec 28, const "穰")+ , (dec 32, const "溝")+ , (dec 36, const "澗")+ , (dec 40, const "正")+ , (dec 44, const "載")+ ]+++--------------------------------------------------------------------------------+-- Simplified Characters+--------------------------------------------------------------------------------++simpl_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+simpl_cardinal = simpl_cardinalRepr ∘ struct++simpl_cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+simpl_cardinalRepr =+ render cardinalRepr+ { reprValue = \n → M.lookup n (simpl_syms ∪ trad_syms)+ , reprNeg = Just $ \_ _ → "负"+ }++simpl_syms ∷ (Integral α, IsString s) ⇒ M.Map α (Ctx Exp → s)+simpl_syms =+ M.fromList+ [ (2, \c → case c of+ CtxMul _ (Lit n) _ | n ≥ 1000 → "两"+ _ → "二"+ )+ , (dec 4, const "万")+ , (dec 8, const "亿")+ ]+++--------------------------------------------------------------------------------+-- Financial Characters (Traditional)+--------------------------------------------------------------------------------++finance_trad_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+finance_trad_cardinal = finance_trad_cardinalRepr ∘ struct++finance_trad_cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+finance_trad_cardinalRepr =+ render cardinalRepr+ { 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 =+ M.fromList+ [ (0, const "零")+ , (1, const "壹")+ , (2, const "貳")+ , (3, const "参")+ , (4, const "肆")+ , (5, const "伍")+ , (6, const "陸")+ , (7, const "柒")+ , (8, const "捌")+ , (9, const "玖")+ , (10, const "拾")+ , (100, const "伯")+ , (1000, const "仟")+ , (dec 4, const "萬")+ , (dec 8, const "億")+ ]+++--------------------------------------------------------------------------------+-- Financial Characters (Simplified)+--------------------------------------------------------------------------------++finance_simpl_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+finance_simpl_cardinal = finance_simpl_cardinalRepr ∘ struct++finance_simpl_cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+finance_simpl_cardinalRepr =+ render cardinalRepr+ { 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 =+ M.fromList+ [ (2, const "贰")+ , (6, const "陆")+ , (dec 4, const "万")+ , (dec 8, const "亿")+ ]+++--------------------------------------------------------------------------------+-- Pinyin+--------------------------------------------------------------------------------++pinyin_cardinal ∷ (Integral α, Monoid s, IsString s) ⇒ α → Maybe s+pinyin_cardinal = pinyin_cardinalRepr ∘ struct++pinyin_cardinalRepr ∷ (Monoid s, IsString s) ⇒ Exp → Maybe s+pinyin_cardinalRepr =+ render cardinalRepr+ { 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 =+ M.fromList+ [ (0, const "líng")+ , (1, const "yī")+ , (2, \c → case c of+ CtxMul _ (Lit n) _ | n ≥ 1000 → "liǎng"+ _ → "èr"+ )+ , (3, const "sān")+ , (4, const "sì")+ , (5, const "wǔ")+ , (6, const "liù")+ , (7, const "qī")+ , (8, const "bā")+ , (9, const "jiǔ")+ , (10, const "shí")+ , (100, const "bǎi")+ , (1000, const "qiān")+ , (dec 4, const "wàn")+ , (dec 8, const "yì")+ , (dec 12, const "zhào")+ , (dec 16, const "jīng")+ , (dec 20, const "gāi")+ , (dec 24, const "zǐ")+ , (dec 28, const "ráng")+ , (dec 32, const "gōu")+ , (dec 36, const "jiàn")+ , (dec 40, const "zhēng")+ , (dec 44, const "zài")+ ]