Haskell中Trifecta解析库<|>运算符与try函数使用疑问
问题1解答
<|>是Alternative类型类提供的选择运算符,语义上确实是优先运行左侧解析器,失败后尝试右侧解析器,你描述的「p = a <|> b优先运行解析器a,a失败时再运行解析器b」的基本逻辑是成立的,不过它的分支切换行为和解析器的输入消耗状态强绑定,不是所有失败场景都会触发分支切换。
问题2解答
你遇到的是parsec系解析器的核心规则,trifecta完全遵循这套设计:
只有当左侧解析器没有消耗任何输入就失败时,<|>才会切换到右侧分支;如果左侧解析器已经消耗了部分输入后才失败,会直接返回解析错误,不会触发回退。
你的parseFraction执行流程是先运行decimal匹配数字,输入为10时,decimal会成功消耗掉全部两个字符,接下来匹配char '/'时因为输入为空才失败,这时parseFraction属于「消耗输入后失败」的场景,所以<|>不会切换到右侧的decimal分支,直接返回解析失败。
try的作用就是修正这种失败状态:被try包裹的解析器如果在消耗输入后失败,会自动回滚到解析前的输入位置,把失败状态修改为「未消耗输入的失败」,这时候<|>就会正常触发,用完整的输入去匹配右侧的decimal解析器,得到预期的解析结果。
内容的提问来源于stack exchange,提问作者hanan
相关产品推荐
相关产品推荐

