带有枚举类型的F#类型约束

时间:2017-02-21 02:25:17

标签: generics enums f#

我想编写一个F#函数,它接受一个通用的枚举值,比方说,它将其基础整数值加倍。幸运的是,有一个名为int的内置函数将枚举转换为整数,所以这应该很简单,对吧?这是我的第一次尝试:

let doubler (value : 't when 't : enum<int>) =
    2 * (int value)

遗憾的是,这会产生以下编译器消息:

  

Program.fs(2,10):警告FS0064:此构造导致代码   比类型注释所指示的更不通用。类型变量   已经被限制为'int'类型。

     

Program.fs(2,10):错误FS0071:应用时键入约束不匹配   类型推理变量的默认类型“int”。 'int'类型   不是CLI枚举类型。另见Program.fs(1,28) - (1,42)。考虑   添加更多类型约束

我做错了什么?有没有更好的方法从F#中的通用枚举值中提取底层整数?

1 个答案:

答案 0 :(得分:1)

您需要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:&#39; a - &gt;当&#39; a:enum

时的int

关于您的第一个错误,int是特殊的,从某种意义上说它也是一个功能。正如您所指出的,您可以在枚举中使用基础类型约束,但在这种情况下,请明确说明类型,因此不会产生混淆:

let double2 (x:'T when 'T:enum<int32>) =
   2 * EnumToValue(x)

很遗憾,如果不使用int,您仍然无法投放到EnumToValue。可能是编译器问题,或其他。也许EnumToValue的内部可以给出一个提示?