kru*_*pen 2 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)
Run Code Online (Sandbox Code Playgroud)
但是我更喜欢Foo构造函数采用两个参数而不是元组:
data Foo = Foo Bar Bar
Run Code Online (Sandbox Code Playgroud)
编写这样一个解析器的最佳方法是什么?理想情况下,我想重用标准的Parsec解析器,angles并尽可能使用applicative.
编写这样一个解析器的最佳方法是什么?理想情况下,我想重用标准Parsec解析器这样的角度,并尽可能使用applicative.
在应用程序风格中,您的解析器将是
foo = angles $ Foo <$> bar <* comma <*> bar
Run Code Online (Sandbox Code Playgroud)
从里到外,a bar被解析,然后是a comma,被丢弃,而另一个bar,然后构造函数Foo被应用于两个被解析的bars.最后,所有都被包裹在angles组合器中,以便形成一个字符串
< bar , bar >
Run Code Online (Sandbox Code Playgroud)
被解析(bar应该使用尾随空格).
将解析器的结果*>与<*应用组合器相结合的解析器消除了对组合器的需要,pair并且很容易推广给构造函数采用任意数量的参数.
正如CA McCann在评论中提到的那样,(<$)组合器(它是GHC的Functor类实现的一部分,具有默认实现(<$) = fmap . const;但它不是语言标准的一部分)也是有用的,如果你想忽略一个前导令牌.使用它,你可以写
Foo <$ ignoreMe <*> bar <* comma <*> baz
Run Code Online (Sandbox Code Playgroud)
这比使用括号更好
Foo <$> (ignoreMe *> bar) <* comma <*> baz
Run Code Online (Sandbox Code Playgroud)
或者pure,
pure Foo <* ignoreMe <*> bar <* comma <*> baz
Run Code Online (Sandbox Code Playgroud)
如果没有它,将以某种形式要求.