3

我有两个用于不同类型术语的解析器。

a :: Parser A
b :: Parser B

我有一个表示这些术语序列的数据类型。

data C = C [A] [B]

如果我的输入是一系列混合术语,那么将s 与sc :: Parser C分开并保留它们的顺序的好方法是什么?例如,给定这些定义:AB

data A = A Char
data B = B Char
a = A <$> oneOf "Aa"
b = B <$> oneOf "Bb"

"abAbBBA"将解析为序列aAAbbBB. 我有一种需要使用的感觉StateT,但不确定具体细节,只需要朝着正确的方向推进。

4

2 回答 2

7

一个简单的解决方案是首先将其解析为一个列表,Either A B然后将partitionEithers其拆分为两个列表,然后将C构造函数应用于这些列表。

c :: Parser C
c = uncurry C . partitionEithers <$> many ((Left <$> a) <|> (Right <$> b))
于 2012-05-02T16:41:01.870 回答
4

为了解决您的问题,我将使用 Data.Either 中的 partitionEithers,代码未选中,但应该不会太远......

c :: Parser C
c = (post . partitionEithers ) <$> many1 aORb
  where
    post (as,bs) = C as bs


aORb :: Parser (Either A B)
aORb = (Left <$> a) <|> (Right <$> b)

编辑 -

折断!

于 2012-05-02T16:43:43.167 回答