0

In C#, the following ASP.NET code is valid:

class A {
    public void WithService<IService, Service>(IServiceCollection serviceCollection) where IService : class where Service : class, IService {
        serviceCollection.AddTransient<IService, Service>();
    }
}

However, the (seemingly) equivalent code in F# is not valid:

type A() =
    member this.WithService<'IService, 'Service when 'IService: not struct and 'Service: not struct and 'Service :> 'IService>(serviceCollection: IServiceCollection) = 
        serviceCollection.AddTransient<'IService, 'Service>() |> ignore

Error FS0663 This type parameter has been used in a way that constrains it to always be ''IService when 'IService: not struct'

Error FS0661 One or more of the explicit class or function type variables for this binding could not be generalized, because they were constrained to other types

Error FS0698 Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution

What's wrong?

jmcilhinney
  • 50,448
  • 5
  • 26
  • 46
Franco Tiveron
  • 2,364
  • 18
  • 34

1 Answers1

3

This is indeed a limitation in F#, you can't have a subtype constraint on two type parameters, ie 'T :> 'U. I think there's a language design suggestion to remove this limitation, although I can't find it right now.

Tarmil
  • 11,177
  • 30
  • 35