gpt4 book ai didi

f# - 在记录之间复制属性

转载 作者:行者123 更新时间:2023-12-03 09:56:58 25 4
gpt4 key购买 nike

在其他几种与状态相关的类型中,我的代码中有以下记录类型:

type SubmittedSuggestionData = {
SuggestionId : Guid
SuggestionText : string
Originator : User
ParentCategory : Category
SubmissionDate : DateTime
}

type ApprovedSuggestionData = {
SuggestionId : Guid
SuggestionText : string
Originator : User
ParentCategory : Category
SubmissionDate : DateTime
ApprovalDate : DateTime
}

然后将它们输入以下内容:
type Suggestion = 
| SubmittedSuggestion of SubmittedSuggestionData
| ApprovedSuggestion of ApprovedSuggestionData

这使我能够使用状态机样式模式来执行依赖于状态的特定业务逻辑。 (此方法取自: http://fsharpforfunandprofit.com/posts/designing-with-types-representing-states/)

我有一个函数,它以最简单的形式更改 SubmittedSuggestionApprovedSuggestion :
let ApproveSuggestion suggestion =
match suggestion with
| SubmittedSuggestion suggestion -> ApprovedSuggestion {}

此功能目前不完整,因为我正在努力理解的是,当建议从已提交更改为已批准时,如何从传入的 suggestion 复制属性进入新创建的 ApprovedSuggestion同时还填充了 ApprovalDate 的新属性?

我想如果我做类似的事情会起作用:
let ApproveSuggestion suggestion =
match suggestion with
| SubmittedSuggestion {SuggestionId = suggestionId; SuggestionText = suggestionText; Originator = originator; ParentCategory = category; SubmissionDate = submissionDate} ->
ApprovedSuggestion {SuggestionId = suggestionId; SuggestionText = suggestionText; Originator = originator; ParentCategory = category; SubmissionDate = submissionDate; ApprovalDate = DateTime.UtcNow}

但这对我来说看起来很可怕。

有没有更简洁、更简洁的方法来获得相同的结果?我试过使用 with关键字,但它没有编译。

谢谢

最佳答案

如果类型之间有很大的重叠,那么考虑分解通常是个好主意。例如,类型可能如下所示:

type SuggestionData = {
SuggestionId : Guid
SuggestionText : string
Originator : User
ParentCategory : Category
SubmissionDate : DateTime
}

type ApprovedSuggestionData = {
Suggestion : SuggestionData
ApprovalDate : DateTime
}

根据类型之间的用法和差异,还可以考虑仅在有区别的联合中拥有批准的类型,完全跳过第二种类型:
type Suggestion = 
| SubmittedSuggestion of SuggestionData
| ApprovedSuggestion of SuggestionData * approvalDate : DateTime

反对这种分解的一个常见论点是,对层次结构更深层次的类型成员的访问变得更加冗长,例如 approvedSuggestionData.Suggestion.Originator .虽然这是真的,但如果冗长变得烦人,属性可以用于转发常用的成分成员,并且任何缺点都应该与优点进行权衡:类型中的代码重复较少,并且更细化的类型提供的任何操作都可以可以从组合类型中获得。

从未经批准的建议和批准日期轻松构建批准建议的能力是一种有用的情况。但可能还有更多:例如,有一个操作可以验证所有建议的用户和类别,无论是否批准。如果持有 Originator 的类型和 ParentCategory已批准和未批准建议的成员是不相关的,获取这些建议的代码需要复制。 (或者需要创建一个通用接口(interface)。)

关于f# - 在记录之间复制属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34452042/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com