f# - 如何映射/绑定 FParsec 用户状态?
问题描述
我想通过解析器线程化一些状态,但我不想为解析器的所有部分使用单一类型的状态,因为某些类型在解析器的某些部分没有意义,但在其他部分需要. 我可以使用可选值或有区别的联合来制作更大更复杂的状态类型,但我认为这很难看。
所以我希望能够将函数映射到解析器的状态。
具体来说,我想要一个具有以下签名的函数
stateMap: (f:'a->'b) (p:Parser<'x,'a>) -> Parser<'x,'b>
FParsec 中是否存在这样的函数或运算符?如果没有,创建它的惯用方式是什么?
解决方案
通过查看源代码,我的印象是今天没有这样的方法,而且实现起来也不是那么容易。Parser<_>
被定义喜欢这样:
type Parser<'Result, 'UserState> = CharStream<'UserState> -> Reply<'Result>
如果有一种映射方式CharStream<'a>
,CharStream<'b>
那么我们将达到目标。
然而,调查来源CharStream<_>
揭示了一些问题:
- 没有
map
为CharStream<_>
。 CharStream<_>
这IDisposable
意味着在解析开始时FParsec
创建一个实例,CharStream<_>
并且假设这会跟踪整个解析过程。根据现有的创建一个新CharStream<_>
的并使用它似乎与设计不匹配。CharStream<_>
继承CharStream
- 因此CharStream
,在分页方面似乎必须进行繁重的工作,并且CharStream<_>
只是将流与用户状态配对。如果CharStream<_>
使用组合而不是继承,我们可以创建一个新的CharStream<_>
,它仍然使用已经存在的CharStream
但继承是不可能的。我的猜测是这里选择继承是为了避免额外的 deref 并因此节省一些时钟周期(性能对解析器很重要)。
所以我认为复合用户状态的想法听起来很有趣,但据我所知,目前 FParsec 不支持这一点。
推荐阅读
- typescript - 如何将属性更改为类中使用的静态值?
- java - 在使用 2 个分区创建的 Azure 事件中心中,事件中心使用者尝试连接到第 3 和第 4 分区
- python - 将数据帧堆叠在另一个数据帧之上
- python - 在使用 bs4 和 iframe 从 HTML 中提取数据时需要帮助
- variables - 只用几个 awk 命令将变量传递给 awk 脚本
- spring-security - LDAP 对象类是否可以在春季提及
- wordpress - 使子域也受到保护 https://
- python - 自动下载多个 pdf 文件中的所有链接(PDF)
- mongodb - MongoDB 聚合,表格类型结果
- r - 如果观察连续出现,则删除重复项,顺序很重要