I seem to be coming across mapping keywords straight to a datatype fairly often and I solve it as below. It can quickly get out of hand as you have to repeat the string values.
Is there a more compact way to express this?
import Text.ParserCombinators.Parsec
data Keyword = Apple | Banana | Cantaloupe
parseKeyword :: Parser Keyword
parseKeyword = ( string "apple"
<|> string "banana"
<|> string "cantaloupe"
) >>= return . strToKeyword
where strToKeyword str = case str of
"apple" -> Apple
"banana" -> Banana
"cantaloupe" -> Cantaloupe
EDIT:
As a followup question, since this seemed to be too easy. How would the compact solution work with try?
E.g.
import Text.ParserCombinators.Parsec
data Keyword = Apple | Apricot | Banana | Cantaloupe
parseKeyword :: Parser Keyword
parseKeyword = ( try (string "apple")
<|> string "apricot"
<|> string "banana"
<|> string "cantaloupe"
) >>= return . strToKeyword
where strToKeyword str = case str of
"apple" -> Apple
"apricot" -> Apricot
"banana" -> Banana
"cantaloupe" -> Cantaloupe