2012-05-02 27 views
3

对于不同类型的术语,我有两个解析器。解析期间对不同类型的术语进行分区

a :: Parser A 
b :: Parser B 

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

data C = C [A] [B] 

如果我输入的混合条款的顺序,什么是写c :: Parser CA■从B小号分开,维护他们的订单的好方法?例如,给定这些定义:

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

"abAbBBA"将解析到序列aAAbbBB。我有一种感觉,我需要使用StateT,但我不确定具体情况,只需要朝正确的方向推动。

回答

7

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

c :: Parser C 
c = uncurry C . partitionEithers <$> many ((Left <$> a) <|> (Right <$> b)) 
+0

非常好,非常感谢。在我的脑海中,我绝对是过于复杂。 –

4

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

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) 

编辑 -

快照!

相关问题