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 = []}}
这是一个非常轻量级的解决方案,您将编写更少的代码,但它会改变您的设计,这取决于您的其余代码是否有意义。
我正在尝试构建一个通用函数来操作记录我的代码如下所示:
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 = []}}
这是一个非常轻量级的解决方案,您将编写更少的代码,但它会改变您的设计,这取决于您的其余代码是否有意义。