2016-02-03 2 views
5

В е # проекта У меня есть следующие типы:F # Тип Constraint Несовпадение при использовании ограничения на функции общего

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'

Удаление inline из определения функции дает мне компиляции ошибки времени:

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.

То, что я пытаюсь достичь иметь функцию, которая принимает обобщенный тип со свойством конкретного имени, «Name» в этом случае. Что я делаю неправильно или что мне не хватает?

ответ

5

Проблема заключается в том, как вы вызываете ограниченный член - вы не можете использовать синтаксис i.Name, но вместо этого должны использовать более подробный синтаксис. На яркой стороне, это позволяет подпись самого метода, который будет судить, так что вы не должны дублировать все:

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

Отметим также, что вы должны использовать статически разрешенное переменную типа (^a) вместо переменной обычного типа ('a).

+0

удивительный, спасибо чувак –

Смежные вопросы