1
11
没有人在函数式语言中使用访问者模式——这是一件好事。有了模式匹配,幸运的是,只需使用(相互)递归函数,就可以更容易和直接地实现相同的逻辑。 例如,假设您想为AST编写一个简单的解释器:
访问者模式通常只会使这一点复杂化,尤其是当结果类型是异类时,如这里所示。 |
2
6
如果您必须在一组相互递归的数据类型(例如AST)上编写许多不同的递归操作,那么您可以使用开放递归(以类的形式)来编码遍历,并为自己节省一些麻烦。 在 Real World OCaml . |
3
5
确实可以为每种类型的AST定义一个访问方法(默认情况下不做任何事情),并让您的访问函数将该类的一个实例作为参数。事实上,这种机制在OCaml世界中被使用,尽管并不经常使用。 特别是 CIL library 有访客类 (参见 https://github.com/kerneis/cil/blob/develop/src/cil.mli#L1816 用于接口)。请注意,CIL的访问者本质上是必须的(转换已到位)。然而,定义将AST映射到另一个AST的访问者是完全可能的,例如 Frama-C ,基于CIL,提供现场和复制访问者。最后 Cαml ,是一个AST生成器,用于轻松处理绑定变量、生成映射并将访问者与数据类型一起折叠。 |
4
0
访问者模式(以及与可重用软件相关的所有模式)与包含多态上下文(子类型和继承)中的可重用性有关。 Composite解释了一种解决方案,在该解决方案中,您可以向现有子类型添加新的子类型,而无需修改后者的代码。 Visitor解释了一个解决方案,在该方案中,您可以向现有类型(及其所有子类型)添加新函数,而无需修改类型代码。 这些解决方案属于面向对象编程,需要使用动态绑定发送消息(方法调用)。 您可以在Ocaml中做到这一点,因为您使用了“O”(对象层),但由于具有强类型的优点,会有一些限制。 在OCaml中,有一组相关类型,决定是使用类层次结构和消息发送,还是如andreas所建议的那样,使用具体的(代数)类型以及模式匹配和简单的函数调用,是一个难题。 混凝土类型不等同。如果选择后者,则在定义和编译节点类型之后,将无法在AST中定义新节点。一旦说a是A1或A2,你就不能在不修改源代码的情况下在后面说还有一些A3。 在您的案例中,如果您想要实现访问者,请用类及其子类替换EXPR具体类型,用方法替换函数(顺便说一下,这些方法也是函数)。然后,动态绑定将完成此任务。 |
nanounanue · 使用python和高级操作符的函数管道 6 年前 |
Zazaeil · 这个特定的递归可以用尾部优化的方式重写吗? 6 年前 |
corvid · 使用ramda通过变量进行升序/降序 6 年前 |
CodingNow · Scala:如何制作多种方法并逐一应用? 6 年前 |