1
votes

How can I override an abstract method with a generic type signature, and give it a more specific parameter type in a subclass?

type Rule() =
    abstract Core : 'T -> bool
    default _.Core _ = false

type Entity = {
    Name: string
    State: string
}

type Wisconsin() =
    inherit Rule()
    override _.Core (entity: Entity) =
        entity.State = "WI"

SimpleMemberOverload.fsx(256,22): error FS0001: This expression was expected to have type ''a' but here has type 'Entity'

1
You can't. The base class says that the method accepts any type parameter. If you pass Wisconsin as a Rule, calling Corer should work with any type, not just Entity. - Panagiotis Kanavos
I noticed the file name SimpleMemberOverload.fsx in the error message, and I'm wondering whether there's confusion about overload and override. Those are two very different things. - Bent Tranberg

1 Answers

3
votes

You can't. After all, saying a rule takes any 'T and then having such a rule taking only entities would violate the contract. What should a caller having a reference of type Rule pointing to an object of type Wisconsin expect if e.g. a string is passed to Core?

You could however define various rules like so:

type Rule<'T> () =
    abstract Core : 'T -> bool
    default _.Core _ = false

type Entity = {
    Name: string
    State: string
}

type Wisconsin() =
    inherit Rule<Entity>()
    override _.Core entity =
        entity.State = "WI"

meaning Wisconsin does not narrow the parameter type but now is a rule for/of entities.