Haskell适用于< *和*>

时间:2018-03-18 22:07:52

标签: haskell applicative

所以我在Haskell中创建了一个基本的解析器,我最近学到了这样的东西,而不是像这样:

sumParser = fmap (\_ a _ b _ -> a + b) ws <*> val <*> plus <*> val <*> eof

我可以使用像

这样的东西来清理它
sumParser = fmap (+) ws *> val <* plus *> val <* eof

显然,我实际上并没有这样做,但这只是一个例子。我的问题是,我可以跳过&#39; &#39;返回&#39;使用wsval的某些解析器(?)的值,例如<**>。但是,我对Haskell来说真的很新,而且我不确定这是否有意义或如何查找(我不是真的从Hoogle那里得到它并环顾四周),但我希望能够一起跳过多个。

我的意思是我想改变这样的事情:

ps = fmap (\_ _ a _ _ _ b _ _ -> a+b) ws <*> p1 <*> val <*> ws <*> p2 <*> ws <*> val <*> ws <*> p3

类似

ps = fmap (\a b -> a+b) ws *> p1 *> val <* ws * p2 * ws *> val <* ws <* p3

既然没有编译,我也不确定如果可以这样做怎么查找?

1 个答案:

答案 0 :(得分:4)

根据我的经验,除非在最简单的情况下混合(*>)(<*),否则会让人感到困惑。我倾向于只使用(<*)(以及(<$))变体。然后我可以从左到右依次决定是否要使用&#34; next&#34;项目与否。

在您的示例中,这意味着:

ps = (+) <$ ws <* p1 <*> val <* ws <* p2 <* pw <*> val <* ws <* p3

(此外,假设ws可能是空白的缩写:您可能不应该将空白解析器混合到所有内容中,而是编写可以或多或少地自动解析空白的抽象。常见的技术是定义解析器组合器他们自己最后解析并丢弃空格,或者先做一个lexing pass并让解析器组合器对结果列表/标记流进行操作。)