Generics 枚举类型为的F#类型约束
我想写一个F#函数,它接受一个通用的枚举值,比如说,将其基础整数值加倍。幸运的是,有一个名为Generics 枚举类型为的F#类型约束,generics,enums,f#,Generics,Enums,F#,我想写一个F#函数,它接受一个通用的枚举值,比如说,将其基础整数值加倍。幸运的是,有一个名为int的内置函数可以将枚举转换为整数,所以这应该很容易,对吗?这是我的第一次尝试: let doubler (value : 't when 't : enum<int>) = 2 * (int value) let doubler(值:'t when't:enum)= 2*(整数值) 遗憾的是,这会导致以下编译器消息: fs(2,10):警告FS0064:此构造导致代码 没有类型
int
的内置函数可以将枚举转换为整数,所以这应该很容易,对吗?这是我的第一次尝试:
let doubler (value : 't when 't : enum<int>) =
2 * (int value)
let doubler(值:'t when't:enum)=
2*(整数值)
遗憾的是,这会导致以下编译器消息:
fs(2,10):警告FS0064:此构造导致代码
没有类型注释所指示的那么通用。类型变量
't已被约束为'int'类型
Program.fs(2,10):错误FS0071:应用时类型约束不匹配
类型推断变量的默认类型“int”。类型“int”
不是CLI枚举类型。另见Program.fs(1,28)-(1,42)。考虑
添加更多类型约束
我做错了什么?是否有更好的方法从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
如果检查倍频器的类型签名
:
val-doubler:xEnum:'a->int当'a:enum
关于您的第一个错误,int
是特殊的,从某种意义上说,它也是一个函数。正如您所指出的,您可以在枚举中使用基础类型约束,但在这种情况下,请明确说明类型,这样就不会产生混淆:
let double2 (x:'T when 'T:enum<int32>) =
2 * EnumToValue(x)
let double 2(当'T:enum时x:T)=
2*EnumToValue(x)
不幸的是,如果不使用
EnumToValue
,您仍然无法强制转换到int
。可能是编译器问题或其他问题。也许EnumToValue的内部可以给出一个提示?enum所做的是将一个值转换为它的表示形式。编译器将为您输入约束。看下面。看起来很完美,谢谢。尽管如此,我的代码不起作用似乎还是很奇怪。@brianberns这是因为没有通用枚举(我想)。如果您想要约束,您需要说let doubl2(x:'T when'T:enum)=
。但这将限制x仅为一种枚举类型。您仍然会遇到int
问题。我不知道这个问题的根本原因。我的意思是没有什么像enum
这样的东西。当然,您可以窃取类型签名,并将其显式化:let tripler(xEnum:'a when'a:enum)=3*EnumToValue(xEnum)
。但是,即使没有它,编译器也会给您一个错误,例如char枚举。坦率地说,我真的没有必要在F#中使用enum,因为有du,可能除了命令行参数之外。我不明白你的意思。我很确定enum
在F#中是一个合法的类型约束,尽管文档说它“不用于普通用途”。请参阅。关于这一点的另一个评论是:EnumToValue
将枚举装箱,然后将其作为int解除装箱。这很好,但速度很慢。我真正想要的是性能和本机int
操作符一样好的东西,它在运行时不需要循环。