我想编写一个 F# 函数,它采用通用枚举值,并且将其基础整数值加倍。幸运的是,有一个名为 int
的内置函数可以将枚举转换为整数,所以这应该很容易,对吧?这是我的第一次尝试:
let doubler (value : 't when 't : enum<int>) =
2 * (int value)
遗憾的是,这会导致以下编译器消息:
Program.fs(2,10): warning FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 't has been constrained to be type 'int'.
Program.fs(2,10): error FS0071: Type constraint mismatch when applying the default type 'int' for a type inference variable. The type 'int' is not a CLI enum type. See also Program.fs(1,28)-(1,42). Consider adding further type constraints
我做错了什么?是否有更好的方法从 F# 中的通用枚举值中提取基础整数?
最佳答案
您需要EnumToValue
。
open FSharp.Core.LanguagePrimitives
let doubler xEnum =
2 * EnumToValue(xEnum)
type ColorEnum =
| Red=0
| Yellow=1
| Blue=2
let blue = ColorEnum.Blue
doubler blue
//val it : int = 4
如果您检查doubler
的类型签名:
val doubler : xEnum:'a -> int when 'a : enum
关于您的第一个错误, int
很特殊,从某种意义上说,它也是一个函数。正如您所指出的,您可以在枚举中使用基础类型约束,但在这种情况下要明确类型,这样就不会造成混淆:
let double2 (x:'T when 'T:enum<int32>) =
2 * EnumToValue(x)
不幸的是,如果不使用EnumToValue
,您仍然无法转换为int
。可能是编译器问题,或者其他问题。也许 EnumToValue 的内部结构可以给出提示?
关于generics - F# 具有 Enum 类型的类型约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42357587/