F#中的部分匿名记录

f#

我如何输入一个函数,该函数接受一个具有字段a任何其他字段的记录

在 F# 中是否有可能与此标准 ML函数等效?

fun f {a: string, ...} = "Hello" ^ a;

尝试了以下但这些似乎在语法上无效:

let f (r: {|a: string; _|}) = impl;
let g (r: {|a: string; ...|}) = impl;

回答

您可以使用静态解析类型参数实现这种约束,如下所示:

let inline f< ^T when ^T: (member a: string)> (r: ^T) = ()

f {| a = "yeet" |} // compiles
f {| a = "yeet"; b = "yote" |} // compiles
f {| b = "yote" |} // error

请注意,这不仅适用于匿名记录。它适用于任何具有指定签名成员的类型。

我也喜欢将这些东西隐藏在模块后面,并将讨厌的 SRTP 内容提取到一个活动模式中,如下所示:

module M =
    let inline private (|HasName|) x = (^a : (member Name: string) x)

    let inline printName (HasName name) = printfn $"{name}"

type Person1 = { Name: string; Age: int }
type Person2 = { Name: string; Age: int; IsFunny: bool }

type Name(name) =
    member _.Name = name

let p1 = { Name = "Phillip"; Age = 30 }
let p2 = { Name = "Phillip"; Age = 30; IsFunny = false }
let nm = Name "Phillip"

M.printName p1
M.printName p2
M.printName nm

这样做的好处是隐藏了如何让约束“正确排列”的细节,并让您可以轻松地在其他想要公开的内容中重新使用签名。


以上是F#中的部分匿名记录的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>