如何在没有冗余匹配案例的情况下转换通用变体实例?

How to convert generic variants instance without the redundancy match cases?

我有以下通用变体类型:

type 'a t = A | B | C | D | E | Value of 'a

和一些将 int t 转换为 string t

的函数
let int_to_sting = function
  | Value x -> Value (string_of_int x)
  | some    -> some

此函数无法编译,因为

| some -> some
Error: This expression has type int t but an expression was expected of type string t
Type int is not compatible

甚至它有类型注释。

let int_to_sting : int t -> string t = function
  | Value x -> Value (string_of_int x)
  | some    -> some

我可以用

重写它
let int_to_sting = function
  | Value x -> Value (string_of_int x)
  | A       -> A
  | B       -> B
  | C       -> C
  | D       -> D
  | E       -> E 

但是长长的构造函数列表看起来有些多余。 是否可以在我的第一个实现中转换 some 以避免这种嘈杂的代码?

您可以通过枚举 将它们绑定到一个名称来稍微减少冗余:

let int_to_sting = function
  | Value x -> Value (string_of_int x)
  | (A | B | C | D | E) as some -> some

另一个明显不安全且您绝对不应该使用的选项是使用 Obj.magic:

来规避类型系统
let int_to_sting = function
  | Value x -> Value (string_of_int x)
  | some    -> (Obj.magic (some: int t): string t)

这恰好有效,因为无论类型参数如何,这些值的表示都是相同的。但是,如果您要添加另一个不是...的构造函数,那么您会崩溃并燃烧。