F# |列表上具有 'or' 约束的泛型

标签 f# f#-3.0

我有以下两种类型:

    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/

相关文章:

.net - 如何在F#中创建.NET兼容事件?

f# - F# 3.0 中的事件模式被破坏

.net-4.0 - 可移植 F# 库引用 .NET 4.5(但不是 4.0)

F# Async<'T> 取消如何工作?

F# 查询加入/组/聚合?

使用类型约束的 F# 模式匹配

f# - 定义可区分联合的默认值

f# - 为什么 Async.RunSynchronously 挂起?

lambda - 列表列表、lambda 和过滤结果

f# - 如何在 F# 中从 Excel 获取单元格数据(使用适当的输入)