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

Haskell解析器开发中Applicative操作符<*与*>的使用疑问

简化Haskell解析器的返回值处理

你发现的这个简化技巧真的太赞了!在Parsec这类解析器组合子库中,<*和*>就是专门用来解决这类“只关心解析成功、不需要保留返回值”的场景,完美替代了原来用fmap写一堆占位符的冗余写法。

先拆解下你给出的两个版本:

  • 原来的写法:

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

    这里你不得不手动用_忽略掉ws、plus、eof的返回值,只留两个val的结果做加法,占位符一多,代码不仅啰嗦,可读性也差了不少。

  • 简化后的写法:

    sumParser = fmap (+) ws *> val <* plus *> val <* eof
    

    这两个操作符的作用可以直白理解为:

    • *>:先跑左边的解析器,把它的结果丢了,只保留右边解析器的输出
    • <*:先跑左边的解析器,留住它的结果,把右边解析器的输出丢了

    一步步拆解这个简化版的逻辑:

    1. ws *> val:先解析空白符(结果直接丢),拿到第一个val的值
    2. <* plus:攥着第一个val的值,解析加号(结果丢)
    3. *> val:丢加号的结果,拿到第二个val的值
    4. <* eof:攥着两个val通过fmap (+)组合出来的加法结果,解析结束符(结果丢)

    最终效果和原代码完全一致,但代码简洁太多,逻辑也更一目了然。

其实这俩操作符就是Applicative接口的常用工具,本质上是把你手动写的占位符lambda封装成了通用操作:

  • (*>)等价于(\_ y -> y) <$> a <*> b
  • <*等价于(\x _ -> x) <$> a <*> b

后续你处理更复杂的解析场景时,比如连续跳过多个无关的解析步骤,或者组合多个需要保留的结果,这些操作符会帮你省超多重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:38:30