Haskell <* 和 *> 的应用用法
Haskell Applicative usage of <* and *>
所以我在 Haskell 中创建了一个基本的解析器,我最近了解到,而不是像这样:
sumParser = fmap (\_ a _ b _ -> a + b) ws <*> val <*> plus <*> val <*> eof
我可以使用
之类的东西让它更干净
sumParser = fmap (+) ws *> val <* plus *> val <* eof
显然,我实际上并没有这样做,但这是一个例子。我的问题是,我可以使用 <*
和 *>
'skip' 某些解析器 (?) 的 'return' 值,例如 ws
和 val
。但是,我真的是 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
现在无法编译,我不确定如何查找是否可以这样做?
根据我的经验,除了在最简单的情况下混合使用 (*>)
和 (<*)
之外,它变得非常混乱。我倾向于只使用 (<*)
(和 (<$)
)变体。然后我可以从左到右,只决定是否要使用 "next" 项的结果。
在您的示例中,这意味着:
ps = (+) <$ ws <* p1 <*> val <* ws <* p2 <* pw <*> val <* ws <* p3
(此外,假设 ws
可能是空白的缩写:您可能不应该将空白解析器混合到所有内容中,而是编写或多或少自动解析空白的抽象。常见的技术是定义解析器最后自己解析和丢弃空格的组合器,或者首先进行词法分析并让解析器组合器对生成的 list/stream 个标记进行操作。)
所以我在 Haskell 中创建了一个基本的解析器,我最近了解到,而不是像这样:
sumParser = fmap (\_ a _ b _ -> a + b) ws <*> val <*> plus <*> val <*> eof
我可以使用
之类的东西让它更干净sumParser = fmap (+) ws *> val <* plus *> val <* eof
显然,我实际上并没有这样做,但这是一个例子。我的问题是,我可以使用 <*
和 *>
'skip' 某些解析器 (?) 的 'return' 值,例如 ws
和 val
。但是,我真的是 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
现在无法编译,我不确定如何查找是否可以这样做?
根据我的经验,除了在最简单的情况下混合使用 (*>)
和 (<*)
之外,它变得非常混乱。我倾向于只使用 (<*)
(和 (<$)
)变体。然后我可以从左到右,只决定是否要使用 "next" 项的结果。
在您的示例中,这意味着:
ps = (+) <$ ws <* p1 <*> val <* ws <* p2 <* pw <*> val <* ws <* p3
(此外,假设 ws
可能是空白的缩写:您可能不应该将空白解析器混合到所有内容中,而是编写或多或少自动解析空白的抽象。常见的技术是定义解析器最后自己解析和丢弃空格的组合器,或者首先进行词法分析并让解析器组合器对生成的 list/stream 个标记进行操作。)