【问题标题】:Circular Type Constraints圆形类型约束
【发布时间】:2012-05-05 08:54:38
【问题描述】:

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

IState 采用类型参数来控制它通过 get 操作返回的操作类型, IAction 接受一个类型参数来控制它可以作用于哪种状态。 (按排序,我 ment 实现)。 我希望能够保证 State 只返回可以作用于同一类型状态的操作。

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) 不是一个东西。 我怎样才能有一个类型约束来确保我的类型参数的类型等于我定义的类型?

【问题讨论】:

    标签: .net generics f#


    【解决方案1】:

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

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

    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
    

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

    【讨论】:

    • “我希望人们不要开始使用第二种解决方案,并用我的名字命名设计模式”哈哈。就像得了一种以你命名的疾病。
    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 2012-09-06
    • 2017-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多