我想为尖括号中逗号分隔的一对值编写一个解析器。我通过以下方法让它工作:
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
编写这样的解析器的最佳方法是什么?理想情况下,我想重用标准秒差距解析器,例如角度,并尽可能多地使用应用程序。
最佳答案
What is the best way to write such a parser? Ideally I would like to reuse standard Parsec parsers such a angles and use applicative as much as possible.
在应用风格中,你的解析器将是
foo = angles $ Foo <$> bar <* comma <*> bar
从里到外,一个 bar
被解析,然后是 comma
,被丢弃,另一个 bar
,然后构造函数 Foo
应用于两个已解析的bar
s。最后,所有内容都包含在 angles
中。组合器,以便得到以下形式的字符串
< bar , bar >
已解析(bar
可能应该消耗尾随空格)。
将忽略其中一个结果的解析器与 *>
结合起来和<*
应用组合器消除了对 pair
的需要组合器,并且可以轻松推广到采用任意数量参数的构造函数。
如C.A. McCann在评论中提到,(<$)
如果您想忽略前导标记,combinator(它是 Functor
类的 GHC 实现的一部分,默认实现 (<$) = fmap . const
;但它不是语言标准的一部分)也很有用。使用它,你可以写
Foo <$ ignoreMe <*> bar <* comma <*> baz
这比使用括号更好
Foo <$> (ignoreMe *> bar) <* comma <*> baz
或pure
,
pure Foo <* ignoreMe <*> bar <* comma <*> baz
如果没有它,就需要某种形式。
关于haskell - 具有两个参数的构造函数的应用样式解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14067552/