枚举上的 F# 类型约束

标签 f# enums

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

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/

相关文章:

.net - String 和 Stream 的 .NET MD5 Hash 之间的区别

java - 从许多枚举的值中查找枚举的最佳方法

JAVA:按序号返回枚举对象名称

java - 注释异常 : Use of @OneToMany or @ManyToMany targeting an unmapped class:

f# - 纯函数式语言中的 η 展开

c# - 抽象类型定义 f#

java - 如何从通用枚举类型中检索常量的接口(interface)?

c# - 获取 Enum<T> 值 描述

c# - 从 F# 代码使用 C# 中定义的扩展方法

c# - 使用或不使用程序集重定向都找不到 F# Core 方法。我还可以做些什么?