undo_all
undo_all

Reputation: 139

(Haskell) Displaying a list in plain English?

I've been writing a really simple text game engine, and I've come across a problem: I need to be able to print a list of items in plain english. So essentially, I need a function that takes an array of strings and outputs them like how an English speaker would say them. For example:

showEnglish ["door", "car", "cat", "apple"] = "a door, a car, a cat, and an apple."

Is there a clean and fast way to do this in haskell? Thanks.

Upvotes: 1

Views: 102

Answers (2)

MathematicalOrchid
MathematicalOrchid

Reputation: 62848

Problem 1: In English, some words get prefixed with "a", while others get "an". It ought to be possible to fix that like so:

prefixWord :: String -> String
prefixWord "" = ""
prefixWord word =
  if (toLower $ head $ word) `elem` "aeiou"
    then "an " ++ word
    else "a "  ++ word

Problem 2: Join them all together, with an "and" at the end.

joinWords :: [String] -> String
joinWords ws = (intercalate ", " (init ws)) ++ " and " ++ last ws

Put it all together:

showEnglish :: [String] -> String
showEnglish = joinWords . map prefixWord

Upvotes: 4

Christian Conkle
Christian Conkle

Reputation: 5992

You can find the indefinite determiner for a word, roughly speaking, using indefiniteDet from the minimorph package. It looks like the package is intended for just this "ad hoc" usage. It also has a function to insert commas, which unfortunately is anathema because it omits the Oxford comma. So maybe just use intercalate instead. But:

showEnglish :: [Text] -> Text
showEnglish = commas "and" . map (\w -> indefiniteDet w `append` " " `append` w)

ghci> showEnglish ["door", "car", "cat", "apple"]
"a door, a car, a cat and an apple"

And now we don't need to hard-code simplified expectations of English morphology... we'll leave that to whoever wrote minimorph.

Upvotes: 4

Related Questions