如何在不限于一个文件的情况下在F#中实现访客模式?

Chi*_*nke 4 f# visitor-pattern

以下代码示例演示了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"
Run Code Online (Sandbox Code Playgroud)

这样可以很好地编译,但是IVisitable由于使用了and关键字,我们只能在一个文件中实现所有类型。该关键字似乎对于允许相互类型引用是必需的。

有没有一种方式可以实现这种模式,使我们不限于一个文件?

(我不是要问您是否应该在F#中使用此模式)

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

Vor*_*ato 6

模式匹配应该以很少的复杂性和开销实现相同的目标。以我的个人经验,这是在F#中实现访客模式的最佳方法。

type Visitor = A of int | B of int

match a with 
| A x -> 1 * x
| B x -> 2 * x
Run Code Online (Sandbox Code Playgroud)

然后对于一些可能的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();
    }
}
Run Code Online (Sandbox Code Playgroud)