0

假设我在 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.

有什么建议么?

4

2 回答 2

2

每当您发现自己想要进行忽略构造函数的模式匹配时,通常表明您想要重构您的类型以拥有一个新的枚举字段而不是旧的数据构造函数标签:

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

然后,您可以轻松地进行所需的模式匹配:

eat_token (Token _ p) tk2 = error $ "Syntax Error at: " ++ show p
于 2012-02-27T12:30:01.567 回答
0
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 中编写解析代码,而不是使用预处理器。

于 2012-02-27T08:42:36.910 回答