枚举上的F#类型约束

Gus*_*rra 7 enums f#

我正在尝试从字符串到Enum定义一个通用转换运算符,我想像这样使用它:

let day = asEnum<DayOfWeek>("Monday")
Run Code Online (Sandbox Code Playgroud)

但是这个实现:

let asEnum<'a, 'b when 'a: (new : unit -> 'a) and 'a : struct and 'a :> ValueType and 'a : enum<'b>> text = 
    match Enum.TryParse<'a>(text)  with
    | true, value -> Some value
    | false, _ -> None
Run Code Online (Sandbox Code Playgroud)

我只能这样使用它:

    let day = asEnum<DayOfWeek,_>("Monday")
Run Code Online (Sandbox Code Playgroud)

或这个:

    let day:DayOfWeek option = asEnum("Monday")
Run Code Online (Sandbox Code Playgroud)

如果我'a : enum<'b>从类型约束中完全省略了,我可以随心所欲地使用它,但是如果有人没有指定默认的类型int,我真的不喜欢它,我更喜欢它给出一个编译我指定约束时的时间错误

也许有任何技巧只需指定一个类型参数并让另一个参与?有任何想法吗?

Dan*_*iel 4

不幸的是,为了增强约束,似乎您必须将其全部拼写出来:(正如 kvb 指出的,您可以通过在尖括号之外TryParse添加约束来避免重复约束)'T : enum<int>

这也有效:

let asEnum<'T 
  when 'T : enum<int>
  and 'T : struct
  and 'T :> ValueType
  and 'T : (new : unit -> 'T)> text =
  match Enum.TryParse<'T>(text) with
  | true, value -> Some value
  | _ -> None
Run Code Online (Sandbox Code Playgroud)

如果基础类型不是int

type ByteEnum =
  | None = 0uy

asEnum<ByteEnum> "None" //ERROR: The type 'int' does not match the type 'byte'
Run Code Online (Sandbox Code Playgroud)