F# 通用记录

F# Generic Records

我正在尝试构建一个通用函数来操作记录我的代码如下所示:

type Status = Active | Inactive

type IStatus =
    abstract member Status: Status

type User = 
    { 
        Username : string;
        Status : Status
    }
    interface IStatus with
        member x.Status = x.Status


let ChangeStatus<'T when 'T :> IStatus> newStatus (t:'T) =
    {t with Status = newStatus}

现在我得到以下错误:

expression was expected to have type
    'T    
but here has type
    User    

显然,我只想为实现 IStatus 的 Records 创建一个类型约束。我是不是也想OO了?或者这种方法有什么优点,我该如何创建这个 ChangeStatus 函数?

感谢您的阅读。

我不认为你想做的是可能的,因为它需要一个 "generic record cloner" 我的意思是一个通用的记录表达式,目前不支持。

您可以为每个子类创建一个克隆方法,这应该可行,但您必须重复代码以克隆记录。它可能是一个通用的解决方案,但涉及反射。

但是,如果您更改设计,您可以获得所需的功能。例如,您可以使用通用嵌套记录:

type Status = Active | Inactive

type StatusRecord<'T> =
    { 
        Item   : 'T
        Status : Status
    }

let changeStatus newStatus t = {t with Status = newStatus}

// TEST

type User  = {Username  : string}
type Group = {Groupname : string; members : User list}

let user  = {Status = Active; Item = {Username = "User1"}}
let group = {Status = Active; Item = {Groupname = "Group1"; members = []}}

这是一个非常轻量级的解决方案,您将编写更少的代码,但它会改变您的设计,这取决于您的其余代码是否有意义。