首页 > 解决方案 > 如何在 F# 中实现访问者模式而不局限于一个文件?

问题描述

以下代码示例演示了访问者模式在 F# 中的实现

module VisitorPattern

    type IVisitor =
        abstract Visit : ObjectA -> unit
        abstract Visit : ObjectB -> unit

    and IVisitable =
        abstract InvokeVisit : IVisitor -> unit

    and ObjectA =
        interface IVisitable with
            member this.InvokeVisit (visitor: IVisitor) =
                visitor.Visit(this)

    and ObjectB =
        interface IVisitable with
            member this.InvokeVisit (visitor: IVisitor) =
                visitor.Visit(this)

    type MyVisitor =
        member this.Visit (a : ObjectA) =
            printfn "Visited object A"

        member this.Visit (b : ObjectB) =
            printfn "Visited object B"

IVisitable这编译得很好,但是由于使用了and关键字,我们被限制在一个文件中实现所有类型。这个关键字似乎是允许相互类型引用所必需的。

有没有办法以不局限于一个文件的方式实现这种模式?

(我不是在征求你是否应该在 F# 中使用这种模式的意见)

编辑:我问这个问题是因为访问者模式在与 C# 代码进行互操作时是相关的。

标签: f#visitor-pattern

解决方案


模式匹配应该以复杂性和开销的一小部分来实现相同的目标。以我个人的经验,这是在 F# 中实现访问者模式的最佳方式。

type Visitor = A of int | B of int

match a with 
| A x -> 1 * x
| B x -> 2 * x

然后对于一些可能的 C#

private static void Main()
{
    Visitor a = Visitor.A(7)
    switch(a){
        case Visitor.A x:
            x.Item * 1;
            break;
        case Visitor.B x:
            x.Item * 2;
            break;
        default:
            throw new ArgumentOutOfRangeException();
    }
}

推荐阅读