使用类型提供程序实例进行鸭子打字

Duck typing with type provider instances

我正在编写一个 F# 脚本来对数据库中的 table 进行操作。所有 table 都有一个 Guid Id 属性。我想在几个地方使用 duck typing 来引用这个 ID。

以这个函数为例:

let inline getAllIds<'a when 'a : (member Id : Guid with get)
                        and 'a : not struct> (table : Table<'a>) =
    table |> Seq.map (fun x -> x.Id)

我曾希望 when 'a : (member Id : Guid with get) 约束允许我在 table 记录上使用 Id 属性,但我收到类型推断错误('a type annotation may be needed'等)。

此外,如果我尝试将没有 Guid Id 属性 的 table 传递给函数,它会正确地抱怨它不支持运算符 get_Id。这似乎向我表明我的语法是正确的,但可能在某处需要额外的约束。我想做的事可行吗?

(我知道我可以将一个函数传递给这个函数来检索 ID...但是那有什么好玩的?!)

我会坚持认为这是重复的,但这是您需要开始的确切代码:

let inline getAllIds< ^a when ^a : not struct> (table : Table< ^a>) =
    table |> Seq.map (fun x -> (^a : (member Id : Guid with get) x))

或者,可以改用以下语法:

let inline getAllIds< ^a when ^a : not struct> (table : Table< ^a>) =
    table |> Seq.map (fun x -> (^a : (member get_Id : unit -> Guid) x))

IIRC,在使用 3.0 之前的 F# 编译器时,需要 后一种语法。