2016-02-03 11 views
5

In einem f # Projekt mit habe ich die folgenden Typen:F # Typ Constraint Mismatch, wenn eine Einschränkung für eine generische Funktion

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

und die folgende Funktion eine Einschränkung auf dem allgemeinen Argument:

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

Das Problem wird erhalte ich die folgenden Kompilierung-Fehler:

Type constraint mismatch. The type

'a

is not compatible with type

C

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

Entfernen.210 von der Funktionsdefinition gibt mir die folgenden Kompilierung-Fehler:

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.

Was ich versuche, ist eine Funktion zu erreichen, die mit einer Eigenschaft eines bestimmten Namen, „Namen“ in diesem Fall eine generische Art nimmt. Was mache ich falsch oder was fehlt mir?

Antwort

5

Das Problem ist, wie Sie das eingeschränkte Mitglied aufrufen - Sie können die i.Name-Syntax nicht verwenden, sondern müssen stattdessen eine ausführlichere Syntax verwenden. Auf der hellen Seite, ermöglicht dies die Signatur der Methode selbst abgeleitet werden, so dass Sie müssen nicht alles duplizieren:

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

Beachten Sie auch, dass Sie verwenden müssen stattdessen einen statisch aufgelösten Typ Variable (^a) einer normalen generischen Variablen ('a).

+0

genial, danke Alter –

Verwandte Themen