【问题标题】:F# - Type Constraints with primitivesF# - 带有原语的类型约束
【发布时间】:2021-08-19 15:53:27
【问题描述】:

我想添加类型约束,如下所示。当我这样做时,我得到了错误

error FS0698: Invalid constraint: 用于约束的类型是密封的,这意味着约束只能由最多一种解决方案满足

type PropertyValue<'T when 'T :> System.Int16 and 'T :> System.String> = 
   | Single of 'T
   | Array of 'T[] 

这就是我想要做的。

type PropertyValueInfo =
  | String of string
  | Int of int
  | StringArray of string[]
  | IntArray of int[]

在我们的域中,用户可以定义属性,属性可以是字符串、整数或字符串和整数的数组版本。我试图在一般意义上对此进行建模,以便将来我可以添加双精度类型。

【问题讨论】:

  • 不能有类型 'TInt16String 的子类型。
  • 您能详细说明您想要实现的目标吗?例如,您的问题的具体情况是什么。为什么你的属性值不能有不同的类型,例如Int 属性,字符串属性?
  • 你也不能子类型Int16
  • 感谢 Fyodor、Koenig 和 Phillip 的快速回复。这就是我想要做的。
    type PropertyValueInfo = | String of string | Int of int | StringArray of string[] | IntArray of int[]
    在我们的域中,用户可以定义属性,属性可以是字符串、整数或字符串和整数的数组版本。我试图在一般意义上对此进行建模,以便将来我可以添加双重类型。希望这是有道理的。谢谢

标签: generics f#


【解决方案1】:

不可能使用“或”作为类型约束,而且它没有真正的意义——常见的类型是什么?

另一种建模方法是使用两个 DU:

type PropertyValue<'T> =
  | Single of 'T
  | Multiple of 'T list

type PropertyType =
  | Int of PropertyValue<int>
  | String of PropertyValue<string>

let singleString = String (Single "hello")
let multInt = Int (Multiple [41; 42])

【讨论】:

  • 您的意思是“不能使用 and 作为类型约束”吗?
  • 其实没有:),我可以看到问题是使用and,但问题是关于将参数限制为int string
  • 但您的示例显示了如何使用“或”,例如联合类型:)
  • 我敢肯定我们在这里的意思是一样的 :),但最初的段落只是为了强调这个问题似乎是在寻找一个通用或约束,然后答案的其余部分显示如何使用 DU 来代替。
  • 是的,我不同意这种措辞,严格来说,您可以使用“或”进行类型约束,它们被称为 DU 或联合类型。从数学上讲,您也可以做“和”,例如类型交集,但在 F# 中不受支持,例如在 OWL 中。你的例子很好:) 希望对 OP 有所帮助。
猜你喜欢
  • 2016-11-13
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-05
相关资源
最近更新 更多