You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell regex-applicative中*>操作符为何未丢弃左参数值?

问题分析:你的理解有误,并非库的问题

核心混淆点:$> 和 *> 在 regex-applicative 中的本质区别

这两个操作符的作用完全不同,你误用了$>的场景:

  • *>(Applicative 顺序组合):依次运行两个解析器,先消耗第一个解析器匹配的输入,再消耗第二个的输入,最终返回第二个解析器的结果(丢弃第一个的结果),这才是你想要的“丢弃前序匹配,保留后续结果”的逻辑。
  • $>(Functor 结果替换):仅运行第一个解析器并消耗其输入,直接返回你指定的纯值作为结果——右边的内容是一个固定值,不是解析器,不会被执行。

你的代码为什么会得到意外结果

你的代码:

nicBeg = ((psym $ not . isSpace) $> (few anySym <> " adapter ")) *> some anySym
result = match nicBeg "abcd adapter NIC 1"

实际执行流程:

  1. psym $ not . isSpace 匹配并消耗输入的第一个字符 a。
  2. $> 把这个解析器的结果替换成 few anySym <> " adapter " 这个解析器本身(而非运行它)。
  3. 后续的 *> 在这里相当于把两个解析器嵌套执行:先运行前面返回的 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"

这里的两个*>依次执行:

  1. 第一个*>:消耗 a 和 bcd adapter ,丢弃这些匹配的结果。
  2. 第二个*>:执行 some anySym 匹配剩余的 NIC 1,返回该结果。

另外补充:few anySym 是非贪婪匹配,会匹配尽可能少的字符直到后续的 " adapter " 能匹配,这部分行为是符合预期的;如果用 many anySym(贪婪匹配),会直接匹配到输入末尾,导致后续的 " adapter " 无法匹配,最终结果为 Nothing。

内容的提问来源于stack exchange,提问作者RandomB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 12:21:09