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

时间:2016-02-03 17:44:36

标签: .net f# inline

在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)

问题是我得到以下编译时错误:

  

类型约束不匹配。类型

     

'a

     

与类型

不兼容      

C

     

“a”类型与“C”类型

不匹配

从函数定义中删除inline会给出以下编译时错误:

  

此代码不够通用。类型变量^ a when   ^ a :(成员get_Name:^ a - &gt;字符串)无法一般化,因为它   会逃避它的范围。

我想要实现的是一个函数,它采用具有特定名称属性的泛型类型,在这种情况下为“Name”。我做错了什么或我错过了什么?

1 个答案:

答案 0 :(得分:6)

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

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

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