2016-02-03 14 views
5

In un progetto F # Ho le seguenti tipologie:F # Tipo di vincolo non corrispondente quando si utilizza un vincolo su una generica funzione

type A = { Name: string } 
type B = { Name: string; SurName: string } 
type C = { Name: string; SurName: string; MaidenName: string } 

e la seguente funzione con un vincolo sul argomento generico:

let inline filterByName<'a when 'a: (member Name: string)> (name: string) (collection: 'a seq) = 
    collection |> Seq.where(fun i -> i.Name = name) 

il problema è ottengo il seguente errore di compilazione:

Type constraint mismatch. The type

'a

is not compatible with type

C

The type ''a' does not match the type 'C'

Rimozione.210 dalla definizione della funzione mi dà il seguente errore di compilazione:

This code is not sufficiently generic. the type variable ^a when ^a:(member get_Name: ^a -> string) could not be generalized because it would escape its scope.

Quello che sto cercando di realizzare è di avere una funzione che prende un tipo generico con una proprietà di un nome specifico, "Nome" in questo caso. Cosa sto sbagliando o cosa mi sto perdendo?

risposta

5

Il problema è come si sta invocando il membro vincolato: non è possibile utilizzare la sintassi i.Name, ma è necessario utilizzare una sintassi più dettagliata. Il lato positivo, questo permette la firma del metodo stesso di dedurre, in modo da non dover duplicare tutto:

let inline filterByName name collection = 
    collection |> Seq.where(fun i -> (^a : (member Name : string) i) = name) 

Si noti inoltre che è necessario utilizzare una variabile di tipo risolti staticamente (^a) invece di una variabile di tipo generico normale ('a).

+0

fantastico, grazie amico –

Problemi correlati