Plural-0.0.2: Language/English/Plural.hs
module Language.English.Plural where
import Data.Map (Map)
import Text.Regex.TDFA
import qualified Data.Map as M
-- | Get plural format.
plural :: String -> String
plural xs = do
let ys = M.filterWithKey (\k _ -> xs =~ k :: Bool) pluralKnowledge
case M.minViewWithKey ys of
-- Get plural format if found match.
Just ((k, a), _) ->
do
let (before, match, _) = xs =~ k :: (String, String, String)
if a =~ "^\\\\&" :: Bool
-- Plural mix `match` part and special suffix if `a` match \\&
-- At this, \\& is speical regex for replace `match` part
-- Example, word `day` with `("[aeiou]y", "\\&s")`, `match` part
-- is `ay`, then `\\&` replace `ay`, and result is `days`.
then do
let (_, _, s) = a =~ "^\\\\&" :: (String,String,String)
before ++ match ++ s
-- Otherwise plural is suffix string.
else before ++ a
-- Otherwise return origianl one.
Nothing -> xs
-- | Try get plural format of word with number.
tryPlural :: Int -> String -> String
tryPlural n s
| n `elem` [0, 1] = s
| otherwise = plural s
-- | The knowledge for plural process.
pluralKnowledge :: Map String String
pluralKnowledge =
M.fromAscList
[("ss$", "sses")
,("zz$", "zzes") -- Example: "buzzes".
,("sh$", "shes")
,("tch$", "tches")
,("eaf$", "eaves")
,("ief$", "ieves") -- Example: "thieves".
,("roof$", "roofs")
,("oof$", "ooves")
,("ife$", "ives")
,("lf$", "lves")
,("[aeiou]y$", "\\&s") -- \\& for replace match string
,("ndum$", "nda") -- Example: "addendum".
,("um$", "a") -- Example: "media", "criteria", "symposia",
-- "crania", curriculum", "data".
,("^die$", "dice")
,("dogma$", "dogmas") -- exception to -ma rule.
,("lemma$", "lemmas") -- exception to -ma rule.
,("schema$", "schemas") -- exception to -ma rule.
,("ia$", "ium") -- Example: "bacteria".
,("ma$", "mata") -- Example: "stigma".
,("na$", "nae") -- Example: "antenna".
,("ta$", "tum") -- Example: "strata".
,("Atlas$", "Atlantes") -- Case-sensitive
,("atlas$", "atlases")
,("Harry$", "Harrys") -- Case-sensitive
,("aircraft$", "aircraft")
,("alga$", "algae")
,("alumna$", "alumnae")
,("alumnus$", "alumni")
,("ameoba$", "ameobae")
,("automaton$", "automata")
,("bacillus$", "bacilli")
,("banjo$", "banjos")
,("beau$", "beaux")
,("cactus$", "cacti") -- Or "cactuses".
,("cannon$", "cannon") -- Or "cannons".
,("canto$", "cantos")
,("cargo$", "cargos")
,("cattle$", "cattle")
,("child$", "children")
,("cod$", "cod")
,("corpus$", "corpora")
,("dwarf$", "dwarves")
,("cs$", "csen") -- Example: "emacsen".
,("foot$", "feet")
,("formula$", "formulae")
,("graffito$", "graffiti")
,("rion$", "ria") -- Example: "criteria".
,("deer$", "deer")
,("focus$", "foci")
,("genus$", "genera")
,("goose$", "geese")
,("hedron$", "hedra") -- Example: "polyhedron".
,("hippopotamus$", "hippopotami")
-- ("index$", "indices") -- "indexes" is also acceptable.
,("insigne$", "insignia")
,("life$", "lives")
,("louse$", "lice")
,("mackerel$", "mackerel")
,("man$", "men")
,("matrix$", "matrices")
,("moose$", "moose")
,("motto$", "mottos")
,("mouse$", "mice")
,("nucleus$", "nuclei")
,("octopus$", "octopi") -- Or "octopuses".
,("offspring", "offspring")
,("opus$", "opera")
,("\\box$", "oxen")
,("panino$", "panini")
,("paparazzo$", "paparazzi")
,("phalanx$", "phalanges")
,("phenomenon$", "phenomena")
,("people$", "people")
,("perch$", "perch") -- Can certain uses of "perch" be plural?
,("piano$", "pianos")
,("police$", "police")
,("portico$", "porticos")
,("quarto$", "quartos")
,("radius$", "radii")
,("rhinoceros$", "rhinoceri") -- Or "rhinoceroses".
-- ("series$", "series") -- Already has an "s".
,("sheep$", "sheep")
-- ("species$", "species") -- Already has an "s".
,("solo$", "solos")
,("syllabus$", "syllabi")
,("terminus$", "termini")
,("ulus$", "uli") -- Example: "stimuli".
,("trout$", "trout")
,("tooth$", "teeth")
,("uterus$", "uteri") -- Or "uteruses".
,("virtuoso", "virtuosi")
,("viscus$", "viscera")
-- ("woman$", "women") -- See "man$".
-- ("e$", "es") -- Fall-through to "[^s]$".
,("is$", "es") -- Example: "axes", "crises", "testes".
,("us$", "uses") -- Example: "campuses", "platypuses", "prospectuses".
,("io$", "ios")
,("oo$", "oos")
,("o$", "oes")
,("y$", "ies")
,("[ei]x$", "ices") -- Example: "vertices".
,("x$", "xes")
,("[^s]$", "\\&s")] -- \\& for replace match string