Соответствие шаблону типа данных на Haskell в Alex - PullRequest
0 голосов
/ 27 февраля 2012

Предположим, у меня есть тип данных в Haskell, подобный этому:

data Token = THEN AlexPosn
            | ELSE AlexPosn

от Алекса, я понял:

data AlexPosn = AlexPn !Int !Int !Int
    deriving (Eq,Show)

Я могу сделать сопоставление с шаблоном так:

eat_token :: Token -> [Token] -> [Token]
eat_token  (THEN p1)((THEN p2):rest) = rest
eat_token  (ELSE p1)((ELSE p2):rest) = rest

Но чего я действительно хочу достичь, так это:

eat_token  (_ p) tk2 = error "Syntax Error at:"++(show p)

Однако я получаю:

Parse error in pattern.

Есть предложения?

Ответы [ 2 ]

2 голосов
/ 27 февраля 2012

Всякий раз, когда вы обнаруживаете, что хотите выполнить сопоставление с шаблоном, в котором игнорируется такой конструктор, обычно это признак того, что вы хотите реорганизовать свой тип, чтобы иметь новое поле перечисления вместо старых меток конструктора данных:

data Token = Token TokenType AlexPosn
data TokenType = THEN | ELSE

Затем вы можете легко выполнить поиск по шаблону:

eat_token (Token _ p) tk2 = error $ "Syntax Error at: " ++ show p
0 голосов
/ 27 февраля 2012
eat_token  (_ p) tk2 = error "Syntax Error at:"++(show p)

Haskell не поддерживает анонимные конструкторы (т. Е. Использование подчеркивания для сопоставления с образцом любого конструктора), даже если все конструкторы типа данных имеют одинаковые элементы.

Вы можете использовать поля записи в вашем типе данных, это автоматически создаст функцию доступа:

data Token = THEN { src_pos :: AlexPosn }
           | ELSE { src_pos :: AlexPosn }

Это создаст функцию src_pos, которую вы можете использовать как любую другую функцию:

eat_token tok ts2 = error "Syntax Error at: " ++ (show (src_pos tok))

Кстати, Алекс (и Хэппи) не особенно дружелюбны для начинающих.В настоящее время большинство людей используют Parsec / Attoparsec.С Parsec вы пишете код синтаксического анализа на Haskell, а не с препроцессором.

...