Haskell中readP解析器输出与预期不符的问题及解决
Haskell readP解析器结果异常的原因与解决方法
问题原因
你看到的输出差异,核心是**>>运算符的行为特性**。>>是Monad的绑定操作,它会执行左侧解析器(t)但直接丢弃其返回值,仅保留右侧解析器(eof)的结果。而eof本身的返回值是()(空元组),所以readP_to_S的输出自然是[((),"")],这完全符合该运算符的设计逻辑。
解决方法
要保留t的解析结果,需要改用能传递结果的组合方式,以下是几种常用方案:
- 使用do表达式(最直观):
readP_to_S $ do num <- t eof return num
先执行t并将结果绑定到num,执行eof确认输入结束,最后返回num,解析"1"时输出[(1,"")],解析"0"时输出[(0,"")]。
- 使用
>>=绑定运算符:
readP_to_S $ t >>= \num -> eof >> return num
逻辑与do表达式完全一致,只是以运算符形式书写。
- 使用Applicative组合子
<*(最简洁):
如果解析器支持Applicative风格,可直接用<*组合:
readP_to_S $ t <* eof
<*会执行左侧解析器并保留其结果,执行右侧解析器但丢弃其结果,完美匹配需求。
内容的提问来源于stack exchange,提问作者Piskator
相关产品推荐
相关产品推荐

