8
votes

I have designed a simple type provider which provide types depending on my parameter. I would like to know if it is possible to define ProvidedTypeDefinitions that would inherit another ProvidedTypeDefinition?

I know that statically I can do the following :

type People() = class end

type Student() =
    inherit People() 

type Teacher() =
    inherit People()

and then I can pattern match like this using Type Test Pattern:

let f (x:People) =
    match x with
        | :? Student -> "Student"
        | :? Teacher -> "Teacher"
        | _ -> "Nothing !!"

What I would like to do in my Type provider is to create ProvidedTypeDefinitions that inherit another ProvidedTypeDefinition. Such that when I use the type provider to generate those types I can pattern match on them (for instance, I know that at runtime one of this types will be instanciated but I don't know which one except that it is one of the ProvidedTypeDefinitions).

Thank you for your time!

2

2 Answers

1
votes

Try using a Discriminated Union for pattern matching instead of inheritance

type Occupation =
  | Student
  | Teacher

type People(occupation) = 
  member this.Occupation = occupation
class end

type Student() =
  inherit People(Student) 

type Teacher() =
  inherit People(Teacher)

let findPerson (person : People) =
  match person.Occupation with
    | Student -> "Student"
    | Teacher -> "Teacher"

I personally like to avoid using object inheritance in fsharp due to upcasting and downcasting. For example,

let person = new Student() :> People
findPerson person

Instead I recommend getting rid of the Student and Teacher parse and let People handle the occupation logic.

type Occupation =
  | Student
  | Teacher

type People(occupation) = 
  member this.Occupation = occupation
class end

let findPerson (person : People) =
  match person.Occupation with
    | Student -> "Student"
    | Teacher -> "Teacher"

People Student
|> findPerson
|> printfn "%s"
0
votes

Inheritance between provided types is pretty hard. You can read this article to get the idea about how you can do this, but even in it you will see that author had little success despite his best efforts. It seems that current implementation of type provider mechanism is not very accommodating in respect with inheritance of provided types from other provided types.

My suggestion for you is much simpler, just use active patterns and you will be able to match on anything you want.

Edit: as a matter of fact, you even do not have to use active patterns, as you can pattern match on type anyway.