简体   繁体   English

F#通用记录

[英]F# Generic Records

I am trying to build a generic function to manipulate a record my code looks like: 我正在尝试构建一个通用函数来处理我的代码如下所示的记录:

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}

Now I get the following error: 现在我得到以下错误:

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

Obviously I just want to create a type constraint for Records which implement IStatus. 显然,我只想为实现IStatus的Records创建类型约束。 Am I thinking too OO? 我是否也想OO? Or is there merit to this approach and how do I create this ChangeStatus function? 还是这种方法有优点,以及如何创建此ChangeStatus函数?

Thank you for reading. 感谢您的阅读。

I don't think it's possible what you're trying to do, because it would need a "generic record cloner" I mean a generic record expression and that's not supported at the moment. 我认为您无法尝试执行此操作,因为它需要“通用记录克隆器”,我的意思是通用记录表达式,目前尚不支持。

You can create a clone method for each subclass, that should work but you will have to repeat the code to clone the record. 您可以为每个子类创建一个克隆方法,该方法应该可以工作,但是您必须重复代码以克隆记录。 It might be a generic solution but involving reflection. 这可能是一个通用解决方案,但涉及反射。

However if you change your design you can get the desired functionality. 但是,如果您更改设计,则可以获得所需的功能。 For instance you can use a generic nested record: 例如,您可以使用通用的嵌套记录:

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 = []}}

This is a very lightweight solution, you will write less code but it will change your design which depending on the rest of your code will make sense or not. 这是一个非常轻量级的解决方案,您将编写更少的代码,但是它将更改您的设计,这取决于您其余的代码是否有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM