具有两个参数的构造函数的应用样式解析器

时间:2012-12-28 09:46:12

标签: haskell parsec applicative

我想在尖括号中为逗号分隔的值对编写解析器。我让它使用以下方法:

pair p1 p2 = do
    x1 <- p1
    comma
    x2 <- p2
    return (x1, x2)

data Foo = Foo (Bar, Bar)

foo :: Parser Foo
foo = Foo <$> (angles $ pair bar bar)

但是我更喜欢Foo构造函数采用两个参数而不是元组:

data Foo = Foo Bar Bar

编写这样一个解析器的最佳方法是什么?理想情况下,我想重用标准的Parsec解析器,例如angles,并尽可能使用applicative。

1 个答案:

答案 0 :(得分:8)

  

编写这样一个解析器的最佳方法是什么?理想情况下,我想重用标准Parsec解析器这样的角度,并尽可能使用applicative。

在应用程序样式中,您的解析器将是

foo = angles $ Foo <$> bar <* comma <*> bar

自上而下,解析bar,然后丢弃comma,另一个bar,然后将构造函数Foo应用于解析后的两个bar angles秒。最后,所有内容都包含在< bar , bar > 组合子中,以便形成

形式的字符串
bar
解析

*>应该使用尾随空格。)

将解析器的结果与<*pair应用组合器相结合,解析器消除了对(<$)组合子的需要,并且很容易推广给构造函数采用任意数量的参数。

作为评论中提及的C.A. McCannFunctor组合子(GHC实施(<$) = fmap . const类的一部分,默认实现Foo <$ ignoreMe <*> bar <* comma <*> baz ;但它不是如果你想忽略一个领先的标记,那么语言标准的一部分也很有用。使用它,你可以写

Foo <$> (ignoreMe *> bar) <* comma <*> baz

比使用括号

更好
pure

pure Foo <* ignoreMe <*> bar <* comma <*> baz

{{1}}
如果没有它,将以某种形式要求。