F# type constraint with Enum type

房东的猫 提交于 2019-12-12 17:06:19

问题


I would like to write an F# function that takes a generic enum value and, let's say, doubles its underlying integer value. Fortunately, there's a built-in function called int that converts an enum to an integer, so this should be easy, right? Here's my first attempt:

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

Sadly, this results in the following compiler messages:

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

What am I doing wrong? Is there a better way to extract the underlying integer from a generic enum value in F#?


回答1:


You need 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

And if you examine the type signature of the doubler:

val doubler : xEnum:'a -> int when 'a : enum

Regarding your first error, int is special, in a sense that it's a function as well. As you point out, you can use an underlying type constraint in the enum, but in that case be explicit about the type, so there is no confusion:

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

Unfortunately you will still not be able to cast to int without using EnumToValue. Could be a compiler issue, or something else. Maybe the internals of EnumToValue can give a hint?



来源:https://stackoverflow.com/questions/42357587/f-type-constraint-with-enum-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!