2016-02-03 22 views
5

私は、次の種類があります。F#型制約が一致しません一般的な機能に制約を使用して、F#プロジェクトで

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

とジェネリック引数に制約を使用して、次の機能:

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

Type constraint mismatch. The type

'a

is not compatible with type

C

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

を削除:

問題は、私は、次のコンパイル時のエラーを取得しています関数定義からは私に、次のコンパイル時のエラーを与える:私が達成しようとしています何

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.

は、この場合には、特定の名前のプロパティを持つジェネリック型を取る機能を持っている「名前」です。私は何が間違っているのですか、何が欠けていますか?

答えて

5

問題は、制限されたメンバーを呼び出す方法です。つまり、i.Name構文を使用することはできませんが、代わりにもっと冗長な構文を使用する必要があります。また、あなたが代わりに静的に解決型変数(^a)を使用する必要があること

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

注:あなたはすべてを複製する必要はありませんので、明るい側では、これは、方法自体の署名を推論することを可能にします通常のジェネリック型変数('a)です。

+0

awesome、thanks dude –