我有两种解析器用于不同类型的术语。
a :: Parser A
b :: Parser B
我有一个表示这些术语序列的数据类型。
data C = C [A] [B]
如果我的输入是一系列混合术语,那么编写c :: Parser C
以将A
与B
分隔开来的好方法是什么,保留他们的订单?例如,鉴于这些定义:
data A = A Char
data B = B Char
a = A <$> oneOf "Aa"
b = B <$> oneOf "Bb"
"abAbBBA"
会解析序列aAA
和bbBB
。我有一种感觉,我需要使用StateT
,但我不确定具体细节,只需要朝着正确的方向努力。
答案 0 :(得分:7)
一个简单的解决方案是首先将其解析为Either A B
列表,然后使用partitionEithers
将其拆分为两个列表,然后将C
构造函数应用于。
c :: Parser C
c = uncurry C . partitionEithers <$> many ((Left <$> a) <|> (Right <$> b))
答案 1 :(得分:4)
要解决您的问题,我会使用Data.an的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)
编辑 -
对齐!