Haskell regex-applicative中*>操作符为何未丢弃左参数值?
问题分析:你的理解有误,并非库的问题
核心混淆点:$> 和 *> 在 regex-applicative 中的本质区别
这两个操作符的作用完全不同,你误用了$>的场景:
*>(Applicative 顺序组合):依次运行两个解析器,先消耗第一个解析器匹配的输入,再消耗第二个的输入,最终返回第二个解析器的结果(丢弃第一个的结果),这才是你想要的“丢弃前序匹配,保留后续结果”的逻辑。$>(Functor 结果替换):仅运行第一个解析器并消耗其输入,直接返回你指定的纯值作为结果——右边的内容是一个固定值,不是解析器,不会被执行。
你的代码为什么会得到意外结果
你的代码:
nicBeg = ((psym $ not . isSpace) $> (few anySym <> " adapter ")) *> some anySym result = match nicBeg "abcd adapter NIC 1"
实际执行流程:
psym $ not . isSpace匹配并消耗输入的第一个字符a。$>把这个解析器的结果替换成few anySym <> " adapter "这个解析器本身(而非运行它)。- 后续的
*>在这里相当于把两个解析器嵌套执行:先运行前面返回的few anySym <> " adapter ",匹配并消耗bcd adapter,得到结果bcd adapter;再运行some anySym匹配剩余的NIC 1,得到结果NIC 1。由于嵌套解析器的特性,最终结果是两个字符串的拼接,也就是bcd adapter NIC 1。
正确写法(替换 $> 为 *>)
把 $> 换成 *> 后,逻辑就符合你的预期了:
nicBeg = ((psym $ not . isSpace) *> (few anySym <> " adapter ")) *> some anySym result = match nicBeg "abcd adapter NIC 1" -- 结果为 Just "NIC 1"
这里的两个*>依次执行:
- 第一个
*>:消耗a和bcd adapter,丢弃这些匹配的结果。 - 第二个
*>:执行some anySym匹配剩余的NIC 1,返回该结果。
另外补充:few anySym 是非贪婪匹配,会匹配尽可能少的字符直到后续的 " adapter " 能匹配,这部分行为是符合预期的;如果用 many anySym(贪婪匹配),会直接匹配到输入末尾,导致后续的 " adapter " 无法匹配,最终结果为 Nothing。
内容的提问来源于stack exchange,提问作者RandomB
相关产品推荐
相关产品推荐

