2016-02-03 14 views
5

Trong một dự án f # Tôi có các loại sau:F # Loại Hạn chế không phù hợp khi sử dụng một hạn chế trên một hàm tổng quát

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

và hàm sau sử dụng một hạn chế về lý luận chung:

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

Vấn đề là tôi nhận được lỗi thời gian biên dịch sau:

Type constraint mismatch. The type

'a

is not compatible with type

C

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

Xóa.210 từ định nghĩa chức năng mang lại cho tôi những lỗi thời gian biên dịch sau:

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.

Những gì tôi đang cố gắng để đạt được là có một chức năng mà phải mất một kiểu chung chung với một tài sản của một tên cụ thể, "Name" trong trường hợp này. Tôi đang làm gì sai hoặc tôi đang thiếu gì?

Trả lời

5

Vấn đề là cách bạn đang gọi thành viên bị hạn chế - bạn không thể sử dụng cú pháp i.Name, nhưng thay vào đó phải sử dụng cú pháp dài dòng hơn. Trên mặt tươi sáng, điều này cho phép chữ ký của phương pháp riêng của mình để được suy ra, vì vậy bạn không cần phải lặp lại tất cả mọi thứ:

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

Cũng lưu ý rằng bạn cần phải sử dụng một loại biến tĩnh giải quyết (^a) thay vì của biến kiểu generic thông thường ('a).

+0

tuyệt vời, cảm ơn anh chàng –

Các vấn đề liên quan