Сопоставьте строку с ее типом данных в Haskell

#haskell

#haskell

Вопрос:

У меня есть следующий тип:

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

Я хочу, чтобы функция отображала представление строки в определенный цвет.

 str2Color :: String -> Color

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

Я мог бы перечислить все строки, но проблема в том, что список всех цветов очень длинный. Есть ли какой-нибудь более простой способ?

ps: Давайте предположим, что все входные строки имеют соответствующий цвет, для простоты изложения.

Комментарии:

1. Вы можете создать deriving Read из Color типа, затем вы можете использовать read :: String -> Color для преобразования строки в соответствующий Color .

2. @WillemVanOnsem работает как шарм. Спасибо.

Ответ №1:

Как отметил @WillemVanOnsem в комментарии, вы можете заставить компилятор создать Read экземпляр для вашего Color типа:

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

который затем делает доступной функцию:

 read :: String -> Color
  

чтобы преобразовать String в соответствующий Color .

Полный пример:

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

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

read выдает исключение, если String значение не является допустимым Color . Чтобы справиться с этим случаем самостоятельно, вы можете использовать Text.Read.readMaybe :: (Read a) => String -> Maybe a и сопоставить результат с шаблоном.

 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    "'")