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 に答える