Reputation: 325
I have the following code:
realWord :: String -> String
realWord s = if elem (map toLower s) ["the","a","of","in","at"] then "" else (map toLower s)
This is to test if a string like "the godfather" contains any number of trivial words such as "the". However, when I put "the godfather" into the function, clearly it gives that this string isn't contained in the list, and spits the sentence out again.
How do I break the sentence "the godfather" into a list of words that I can test individually and then put back together again in a sentence?
My desired output for input "the godfather" is "godfather".
Upvotes: 1
Views: 849
Reputation: 120711
First of all, DRY:
realWord s
| s' `elem` trivial = ""
| otherwise = s'
where trivial = ["the","a","of","in","at"]
s' = map toLower s
So. The problem is, you're not deconstructing the string in any way. What you're trying to do is matching on something and "consuming & throwing away" it when found – that's actually a very basic subtask of parsing.
For this problem, Niklas' solution is probably the best, but to make this more general it's simple enough to use one of the "big weapons":
import Text.Parsec
extractRealWord :: Parsec String u String
extractRealWord = do
skipMany . choice
. map (\w -> string w >> many (oneOf ",. !?\n"))
$ ["the", "a", "of", "in", "at"]
>>= \w@(f:r) -> [w, toUpper f : r]
many . oneOf $ ['a' .. 'z'] ++ ['A' .. 'Z']
To be used e.g.
Prelude Text.Parsec Data.Char> runP extractRealWord ()[] "the godfather"
Right "godfather"
Upvotes: 0