圆形类型约束

时间:2012-05-05 08:54:38

标签: .net generics f#

我有两个接口: IStateIAction。 State有一个方法:GetActions - 返回IActions的集合。 Action有一个方法:Apply - 作用于一个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>

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

1 个答案:

答案 0 :(得分:5)

避免首先解决问题的解决方案

不能直接回答您的问题,但它应该可以解决您原来的问题:

type StateMachine<'State, 'Action> =
    interface
        abstract Apply : 'State * 'Action -> 'State
        abstract GetActions : 'State -> 'Action seq
    end

这种解决问题的方式受到ML's module system

的启发

更丑陋的解决方案

如果你真的想要使用两个紧密耦合的接口,你可以采用这种方式:

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

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