我有以下两种类型:
type MedicalConditionStore = {
MedicalCondition: MedicalCondition
LastMod: UTCTick
}
type RejectedMedicalConditionStore = {
RejectedMedicalCondition: MedicalCondition
LastMod: UTCTick
}
我想创建以下方法:
let accumulateConditions medicalConditionsList =
...
其中medicalConditionsList
可以是MedicalConditionStore列表
或RejectedMedicalConditionStore列表
直觉上,我想将泛型与约束结合起来,但我无法找到正确的语法来做到这一点。我已经尝试过类似的方法,但它不起作用:
let accumulateConditions (medicalConditionsList: ^a list when ^a :(member F: MedicalCondition)) =
...
或者像这样:
let accumulateConditions (medicalConditionsList: RejectedMedicalConditionStore list | MedicalConditionStore list) =
...
任何人都知道如何解决这个问题,而不需要在它们两个上创建另一种有区别的联合类型 - 在这种情况下,我总是需要使用模式将成员从一般类型包装和解开到特定类型,反之亦然匹配吗?
谢谢!
最佳答案
您可以使用静态成员约束来实现此目的,但我认为这是一种错误的方法 - 它将导致脆弱且复杂的代码。
正如评论中提到的,我认为重新考虑您的域名会更有意义。最好的设计实际上取决于医疗条件下可以完成的所有不同的事情。您可以用状态标记条件:
type MedicalConditionState = Rejected | Accepted
type MedicalConditionStore = {
MedicalCondition: MedicalCondition
LastMod: UTCTick
State: MedicalConditionState }
或者您可以在更高级别保留两个单独的列表:
type MedicalConditionStore = {
MedicalCondition: MedicalCondition
LastMod: UTCTick }
type MedicalConditions = {
Accepted: MedicalConditionStore list
Rejected: MedicalConditionStore list }
或者,由于您似乎只想访问基础 MedicalCondition
,您也可以使用良好的老式接口(interface)类型,这在 F# 中是完全合理的做法(尽管在在这种情况下,我认为重新访问您的域模型会更优雅地解决问题):
type IMedicalCondition =
abstract MedicalCondition: MedicalCondition
type MedicalConditionStore =
{ MedicalCondition: MedicalCondition
LastMod: UTCTick }
interface IMedicalCondition with
member x.MedicalCondition = x.MedicalCondition
type RejectedMedicalConditionStore =
{ RejectedMedicalCondition: MedicalCondition
LastMod: UTCTick }
interface IMedicalCondition with
member x.MedicalCondition = x.RejectedMedicalCondition
let accumulateConditions
(medicalConditionsList:seq<#IMedicalCondition>) =
// (...)
关于F# |列表上具有 'or' 约束的泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72847739/