4

I have two interfaces: IState and IAction. A State has a method: GetActions - which returns a collection of IActions. A Action has a method: Apply - which acts on a State, to return a new State.

IState takes a type parameter to control what sort of actions it returns with get actions, IAction takes a type parameter to control what sort of states it can act on. (By sort, i ment implementation). I want to be able to garentee that a State only return actions that can act on a state of that same type.

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>

but obviously typeof(this) is not a thing. How can I have a type constraint making sure my type paramerer is of type equal to the type I am defining?

4

1 回答 1

5

一开始就避免陷入问题的解决方案

不是您问题的直接答案,但它应该可以解决您最初的问题:

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

这种处理问题的方式受到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

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

于 2012-05-05T09:36:12.430 回答