Search code examples
f#type-constraints

Is there a way to define new type parameters in type constraints with F#?


I can't seem to find a way to do something like this:

type Instance<'Aggregate when 'Aggregate :> Aggregate.T<'State,'Event,'Failure>> = {
  ...
  Aggregate: 'Aggregate
  CurrentState: 'State
  ...
}

Notice that I would like to:

  • First define the type parameter within the type constraint
  • Use the type parameter when defining the type

This, of course, does not compile, because 'State is not defined. Are there other ways to do this while preserving the meaning of an instance?

I thought of a few simple ways to do this, but they all lose the meaning. E.g. Instance<'State,'Event,'Failure> isn't quite the same as Instance<'Aggregate>.


Solution

  • All type parameters must be explicit, so you need to include 'State, 'Event, and 'Failure:

    type Instance<'Aggregate,'State,'Event,'Failure when 'Aggregate :> Aggregate.T<'State,'Event,'Failure>> = {
      ...
      Aggregate: 'Aggregate
      CurrentState: 'State
     ...
    }
    

    However, when using this type you should rarely need to explicitly specify those extra parameters. When creating instances the compiler should be able to infer them, and you can probably use an anonymous _ placeholder for some parameters even when you have to name the Instance<_,_,_,_> type explicitly.