圆形类型约束

Lyn*_*ite 4 .net generics f#

我有两个接口: IStateIAction.State有一个方法:GetActions - 返回IActions的集合.一个Action有一个方法:Apply - 作用于一个State,返回一个新的State.

IState接受一个类型参数来控制它通过get动作返回的操作类型,IAction接受一个类型参数来控制它可以作用的状态.(通过排序,我实施).我希望能够保证国家只返回可以对同一类型的国家采取行动的行动.

type IAction<'S when 'S:>IState> =
    abstract member Apply : 'S->'S

and IState<'A when 'A:>IAction<'S when 'S:> typeof(this)>> = 
    abstract member GetActions : seq<'A>
Run Code Online (Sandbox Code Playgroud)

但显然typeof(this)不是一件事.我怎样才能有一个类型约束,确保我的类型参数类型与我定义的类型相同?

Joh*_*Joh 5

解决方案,以避免首先陷入问题

不是你问题的直接答案,但它应该解决你原来的问题:

type StateMachine<'State, 'Action> =
    interface
        abstract Apply : 'State * 'Action -> 'State
        abstract GetActions : 'State -> 'Action seq
    end
Run Code Online (Sandbox Code Playgroud)

ML的模块系统启发了这种解决问题的方法

一个丑陋的解决方案

如果你真的想要使用两个紧密耦合的接口,你可以这样做:

type IState<'Action, 'State when 'Action :> IAction<'State, 'Action> and 'State :> IState<'Action, 'State>> =
    interface
        abstract GetActions : unit -> 'Action seq
    end

and IAction<'State, 'Action when 'Action :> IAction<'State, 'Action> and 'State :> IState<'Action, 'State>> =
    interface
        abstract Apply : 'State -> 'State
    end

// Some stupid types to illustrate how to implement the interfaces
type State() =
    interface IState<Action, State> with
        member this.GetActions() = Seq.empty

and Action() =
    interface IAction<State, Action> with
        member this.Apply s = s
Run Code Online (Sandbox Code Playgroud)

我希望人们不会开始使用第二个解决方案并制作一个以我命名的设计模式:)