在泛型函数上使用约束时 F# 类型约束不匹配

F# Type Constraint Mismatch when using a constraint on a generic function

在一个 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'

从函数定义中删除 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.

我想要实现的是拥有一个函数,该函数采用具有特定名称 属性 的通用类型,在本例中为“名称”。我做错了什么或者我错过了什么?

问题在于您如何调用受约束的成员 - 您不能使用 i.Name 语法,而必须使用更冗长的语法。从好的方面来说,这可以推断出方法本身的签名,因此您不必复制所有内容:

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

另请注意,您需要使用静态解析的类型变量 (^a) 而不是普通的泛型类型变量 ('a)。