Тогда не используйте лексер Haskell.read
функции используют ParSec, который вы можете найти отличное введение в книгу о реальном мире Haskell.
Вот код, который, кажется, работает,
import Text.Read
import Text.ParserCombinators.ReadP hiding (choice)
import Text.ParserCombinators.ReadPrec hiding (choice)
data Tag = CC | CD | DT | EX | FW | IN | JJ | JJR | JJS deriving (Show)
strValMap = map (\(x, y) -> lift $ string x >> return y)
instance Read Tag where
readPrec = choice $ strValMap [
("CC", CC),
("CD", CD),
("JJ$", JJS)
]
просто запустить его
(read "JJ$") :: Tag
Код довольно понятен.Монада синтаксического анализатора string x
соответствует x
, и, если она выполнена успешно (исключение не выдается), возвращается y
.Мы используем choice
, чтобы выбрать среди всего этого.Он будет возвращен соответствующим образом, поэтому, если вы добавите конструктор CCC
, то CC
, частично совпадающий с "CCC", позже потерпит неудачу и вернется к CCC
.Конечно, если вам это не нужно, используйте комбинатор <|>
.