Circular Type Constraints
.net, f#, generics
Solution
A solution to avoid getting into the problem in the first place
Not a direct answer to your question, but it should solve your original problem:
type StateMachine<'State, 'Action> =
interface
abstract Apply : 'State * 'Action -> 'State
abstract GetActions : 'State -> 'Action seq
end
This way of approaching the problem is inspired by ML's module system
An uglier solution
If you really want to go for the two tightly coupled interfaces, you could go that way:
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
I hope people won't start using the second solution and make a design pattern named after me out of it :)
Problem
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?