我正在尝试定义一个从字符串到枚举的通用转换运算符,我想像这样使用它:
let day = asEnum<DayOfWeek>("Monday")
但是有了这个实现:
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
我只能这样使用它:
let day = asEnum<DayOfWeek,_>("Monday")
或这个:
let day:DayOfWeek option = asEnum("Monday")
如果我省略
'a : enum<'b>
完全从类型约束来看,我可以随心所欲地使用它,但是如果有人没有指定类型,它将默认为 int
,我真的不喜欢,我更喜欢它给出一个编译时错误,就像我指定约束时一样也许有什么技巧可以只指定一个类型参数并推断另一个类型参数?有任何想法吗?
最佳答案
不幸的是,为了增加约束,您似乎必须将其全部拼写出来:(正如 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
如果基础类型不是
int
,这会产生编译时错误。 :type ByteEnum =
| None = 0uy
asEnum<ByteEnum> "None" //ERROR: The type 'int' does not match the type 'byte'
关于枚举上的 F# 类型约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15115050/