2016-05-20 15 views
8

Ho progettato un provider di tipo semplice che fornisce tipi in base al mio parametro. Vorrei sapere se è possibile definire ProvidedTypeDefinitions che erediterebbe un'altra ProvidedTypeDefinition?ereditarietà del provider di tipo f #

So che staticamente posso effettuare le seguenti operazioni:

type People() = class end 

type Student() = 
    inherit People() 

type Teacher() = 
    inherit People() 

e poi posso pattern match come questo usando Type Test Pattern:

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

Quello che vorrei fare nella mia Tipo il fornitore è quello di creare ProvidedTypeDefinitions che ereditano un'altra ProvidedTypeDefinition. In modo tale che quando utilizzo il provider di tipi per generare questi tipi, posso eseguire lo schema di corrispondenza su di essi (ad esempio, so che in fase di esecuzione uno di questi tipi verrà instanciato ma non so quale, tranne che è una delle ProvidedTypeDefinitions).

Grazie per il vostro tempo!

risposta

1

Provare a utilizzare un'Unione Discriminazione in per il pattern matching invece di eredità

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" 

mi piace personalmente a evitare di usare l'ereditarietà oggetto in FSharp a causa di upcasting and downcasting. Ad esempio,

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

Invece mi raccomando di eliminare l'analisi Studente e Insegnante e lasciare che le persone gestiscano la logica di occupazione.

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

Grazie per il vostro aiuto :). Il problema con questa soluzione è che TP non fornisce DU o Records. Non sarò in grado di fornire il tipo di 'Occupazione' che hai descritto. – Leleutch

+0

Ciao Leleutch, Ho modificato la mia risposta per accettare il tipo di restrizione –

0

L'ereditarietà tra i tipi forniti è piuttosto difficile. Puoi leggere questo article per avere un'idea di come puoi farlo, ma anche in esso vedrai che l'autore ha avuto scarso successo nonostante i suoi migliori sforzi. Sembra che l'attuale implementazione del meccanismo del type provider non sia molto accomodante rispetto all'ereditarietà dei tipi forniti da altri tipi forniti.

Il mio suggerimento per voi è molto più semplice, basta usare active patterns e sarete in grado di abbinare su tutto ciò che volete.

Modifica: in effetti, non è nemmeno necessario utilizzare i pattern attivi, in quanto è possibile eseguire lo schema di corrispondenza in base al tipo.

Problemi correlati