module Language.Dutch ( sentence_to_Dutch, noun_to_Dutch ) where import Language import Util.Text import Materials import BodyParts data Plural = Single | Plural data Person = First | Second | Third -- In theory, Dutch has male and female genders, but a) I don't know them -- for most words even though it's my native language, and b) they would -- be needed only in rare occasions, which are not supported by our language -- module yet. data Gender = Common | Neuter deriving Eq sentence_to_Dutch :: Sentence -> String sentence_to_Dutch (BasicSentence subj v obj) = let plural = isPlural (getCount subj) person = getPerson (getNoun subj) -- Special case: "Dat is EEN deur NIET" --> "Dat is GEEN deur" geen = getNegation v == IsNot && getCount obj == Indefinite in capitalize $ join_spaced [ npDutch subj , tverb person plural (getVerb v) , (if geen then geen_npDutch else npDutch) obj , if getNegation v == IsNot && not geen then "niet" else "" , advsDutch (getAdverbs v) ] ++ "." sentence_to_Dutch (DescriptiveSentence subj advs adjs) = let plural = isPlural (getCount subj) person = getPerson (getNoun subj) in capitalize $ join_spaced [ npDutch subj , tverb person plural V_is , advsDutch advs , adjs_normal adjs ] ++ "." sentence_to_Dutch (DirQuestion v obj) = capitalize $ join_spaced [ tverb Third Single (getVerb v) , npDutch obj , if getNegation v == IsNot then "niet" else "" , advsDutch (getAdverbs v) , "in welke richting?" ] noun_to_Dutch :: NounPhrase -> String noun_to_Dutch = npDutch isPlural :: Numeric -> Plural isPlural None = Plural isPlural Definite = Single isPlural Indefinite = Single isPlural (Count n) = if n == 1 then Single else Plural getPerson :: Noun -> Person getPerson PN_you = Second getPerson _ = Third -- Special case for Indefinite noun and negated verb: singular "geen deur". geen_npDutch :: NounPhrase -> String geen_npDutch (NounPhrase n _ as) = join_spaced ["geen", adjs_modified as, tnoun n] npDutch :: NounPhrase -> String npDutch (NounPhrase n None as) = join_spaced ["geen", adjs_modified as, pluralNoun n] -- FIXME: can't do anything with adjectives on a pronoun in dutch. npDutch (NounPhrase n Definite _) | isPronoun n = join_spaced [tnoun n] npDutch (NounPhrase n Definite as) = join_spaced [article, adjs_modified as, tnoun n] where article = if getGender n == Neuter then "het" else "de" npDutch (NounPhrase n Indefinite as) = join_spaced ["een", adjs as, tnoun n] where adjs = if getGender n == Neuter then adjs_normal else adjs_modified npDutch (NounPhrase n (Count 1) as) = join_spaced [numeral 1, adjs_normal as, tnoun n] npDutch (NounPhrase n (Count c) as) = join_spaced [numeral c, adjs_modified as, pluralNoun n] -- Translate a list of adjectives that modify a noun. -- Modify them for definite case or plural. -- (It's the same modification: groot -> grote, etc.) adjs_modified :: [Adjective] -> String adjs_modified as = join_spaced (map adj_mod as) -- Translate a list of adjectives that modify a noun. -- This is the form used for indefinite or singular nouns, -- as in "een groot huis". adjs_normal :: [Adjective] -> String adjs_normal as = join_spaced (map adj as) -- Translate a list of adverbs that modify a verb. advsDutch :: [Adverb] -> String advsDutch as = join_text2 ", " " en " (map adv as) -- Individual word translations adj :: Adjective -> String adj AJ_dirty = "vies" adj AJ_locked = "op slot" adj AJ_broken = "kapot" adj AJ_closed = "dicht" adj AJ_empty = "leeg" adj AJ_strange = "vreemd" adj AJ_smelly = "stinkend" adj AJ_huge = "enorm" adj AJ_large = "groot" adj AJ_small = "klein" adj AJ_tiny = "piepklein" adj AJ_hairy = "harig" adj AJ_bald = "kaal" adj AJ_fast = "snel" adj AJ_slow = "langzaam" adj AJ_red = "rood" adj AJ_green = "groen" adj AJ_brown = "bruin" adj (AJ_MATERIAL Iron) = "ijzeren" adj (AJ_MATERIAL Silver) = "zilveren" adj (AJ_MATERIAL Wood) = "houten" adj (AJ_MATERIAL Glass) = "glazen" adj (AJ_MATERIAL Leather) = "leren" adj (AJ_MATERIAL Liquid) = "vloeibaar" adj (AJ_MATERIAL Stone) = "stenen" adj (AJ_MATERIAL Dirt) = "FIXME" adj_mod :: Adjective -> String adj_mod AJ_dirty = "vieze" -- FIXME: Yuck, what's a good way to say "the locked door" in Dutch? adj_mod AJ_locked = "op slotte" adj_mod AJ_broken = "kapotte" adj_mod AJ_closed = "dichte" adj_mod AJ_empty = "lege" adj_mod AJ_strange = "vreemde" adj_mod AJ_smelly = "stinkende" adj_mod AJ_huge = "enorme" adj_mod AJ_large = "grote" adj_mod AJ_small = "kleine" adj_mod AJ_tiny = "piepkleine" adj_mod AJ_hairy = "harige" adj_mod AJ_bald = "kale" adj_mod AJ_fast = "snelle" adj_mod AJ_slow = "langzame" adj_mod AJ_red = "rode" adj_mod AJ_green = "groene" adj_mod AJ_brown = "bruine" adj_mod (AJ_MATERIAL Liquid) = "vloeibare" adj_mod (AJ_MATERIAL m) = adj (AJ_MATERIAL m) adv :: Adverb -> String adv AV_quickly = "snel" adv AV_silently = "stil" adv AV_already = "al" tnoun :: Noun -> String tnoun PN_you = "je" tnoun PN_it = "het" tnoun PN_that = "dat" tnoun N_sword = "zwaard" tnoun N_helmet = "helm" tnoun N_vial = "flesje" tnoun N_orc = "ork" tnoun N_cave_monster = "grotmonster" tnoun N_door = "deur" tnoun N_doorway = "deuropening" tnoun N_direction = "richting" tnoun (N_BODY Torso) = "romp" tnoun (N_BODY Waist) = "middel" tnoun (N_BODY Neck) = "nek" tnoun (N_BODY Head) = "hoofd" tnoun (N_BODY Ear) = "oor" tnoun (N_BODY Shoulder) = "schouder" tnoun (N_BODY Arm) = "arm" tnoun (N_BODY Hand) = "hand" tnoun (N_BODY Finger) = "vinger" tnoun (N_BODY Leg) = "been" tnoun (N_BODY Foot) = "voet" getGender :: Noun -> Gender getGender PN_you = Neuter -- We don't know the gender and it doesn't matter. getGender PN_it = Neuter getGender PN_that = Neuter getGender N_sword = Neuter getGender N_helmet = Common getGender N_vial = Neuter getGender N_orc = Common getGender N_cave_monster = Neuter getGender N_door = Common getGender N_doorway = Common getGender N_direction = Common getGender (N_BODY Torso) = Common getGender (N_BODY Waist) = Neuter getGender (N_BODY Neck) = Common getGender (N_BODY Head) = Neuter getGender (N_BODY Ear) = Neuter getGender (N_BODY Shoulder) = Common getGender (N_BODY Arm) = Common getGender (N_BODY Hand) = Common getGender (N_BODY Finger) = Common getGender (N_BODY Leg) = Common getGender (N_BODY Foot) = Common pluralNoun :: Noun -> String pluralNoun PN_you = "jullie" pluralNoun PN_it = "ze" pluralNoun PN_that = "die" pluralNoun N_cave_monster = "grotmonsters" pluralNoun N_vial = "flesjes" pluralNoun (N_BODY Shoulder) = "schouders" pluralNoun (N_BODY Neck) = "nekken" pluralNoun (N_BODY Ear) = "oren" pluralNoun (N_BODY Finger) = "vingers" pluralNoun (N_BODY Leg) = "benen" -- Default rule pluralNoun n = tnoun n ++ "en" tverb :: Person -> Plural -> Verb -> String tverb pr pl V_is = -- Special case for "is" case (pr, pl) of (First, Single) -> "ben" (Second, Single) -> "bent" -- Note: "jij bent" vs. "ben jij" not supported (Third, Single) -> "is" (_, Plural) -> "zijn" tverb pr pl v = case (pr, pl) of (First, Single) -> form1 (Second, Single) -> form2 (Third, Single) -> form2 (_, Plural) -> form3 where (form1, form2, form3) = xverb v xverb :: Verb -> (String, String, String) xverb V_hit = ("raak", "raakt", "raken") xverb V_kill = ("dood", "doodt", "doden") xverb V_is = ("ben", "is", "zijn") -- Not correct for Second person! xverb V_open = ("open", "opent", "openen") xverb V_close = ("sluit", "sluit", "sluiten") numeral :: Int -> String numeral 0 = "nul" numeral 1 = "\xe9\xe9n" -- E9 is e' numeral 2 = "twee" numeral 3 = "drie" numeral 4 = "vier" numeral 5 = "vijf" numeral 6 = "zes" numeral 7 = "zeven" numeral 8 = "acht" numeral 9 = "negen" numeral 10 = "tien" numeral 11 = "elf" numeral 12 = "twaal" numeral 13 = "dertien" numeral 14 = "veertien" numeral 15 = "vijftien" numeral 16 = "zestien" numeral 17 = "zeventien" numeral 18 = "achttien" numeral 19 = "negentien" numeral 20 = "twintig" numeral 30 = "dertig" numeral 40 = "veertig" numeral 50 = "vijftig" numeral 60 = "zestig" numeral 70 = "zeventig" numeral 80 = "tachtig" numeral 90 = "negentig" numeral n | n > 20 && n < 100 = let singles = n `mod` 10 in numeral singles ++ "en" ++ numeral (n - singles) numeral 100 = "honderd" numeral n | n < 1000 && n `mod` 100 == 0 = numeral (n `div` 100) ++ "honderd" numeral 1000 = "duizend" numeral n | n < 10000 && n `mod` 1000 == 0 = numeral (n `div` 1000) ++ "duizend" -- Default: just print the number numeral n = show n