Map String to its data type in Haskell

Viewed 215

I have the following type:

data Color = Red
           | Yellow
           | Green
           | ...

I want a function mapping string representation to specific Color.

str2Color :: String -> Color

str2Color "Red": Red
str2Color "Yellow": Yellow
str2Color "Green": Green

I could enumerate all strings, but problem is the list of all colors is very long. Is there any simpler way?

ps: Let's assume all input strings have a corresponding Color, for ease of exposition.

1 Answers

As @WillemVanOnsem noted in a comment, you can have the compiler derive a Read instance for your Color type:

data Color = Red | Yellow | Blue
  deriving (Read, Show)

which then makes available the function:

read :: String -> Color

to convert a String to the corresponding Color.

Full example:

data Color = Red | Yellow | Blue
  deriving (Read, Show)

main = do
  print (read "Red" :: Color)
  print (read "Blue" :: Color)
  

read throws an exception if the String isn’t a valid Color. To handle this case yourself, you can use Text.Read.readMaybe :: (Read a) => String -> Maybe a and pattern-match on the result.

import Text.Read (readMaybe)

main = do
  print (readMaybe "Red" :: Maybe Color)    -- Just Red
  print (readMaybe "Beans" :: Maybe Color)  -- Nothing
  s <- getLine
  case readMaybe s of
    Just color -> print (color :: Color)
    Nothing -> putStrLn ("Invalid color: '" ++ s ++ "'")
Related