带Enum类型的F#类型约束 [英] F# type constraint with Enum type

查看:149
本文介绍了带Enum类型的F#类型约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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:此构造使得代码的类型通常比类型注释所指示的要少
。类型变量
't被限制为类型'int'。

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:类型约束不匹配时对类型推断变量应用
默认类型'int'。类型'int'
不是CLI枚举类型。另请参阅Program.fs(1,28) - (1,42)。考虑
进一步添加类型限制

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#中的泛型枚举值中提取底层整数?

What am I doing wrong? Is there a better way to extract the underlying integer from a generic enum value in 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 的类型签名:

And if you examine the type signature of the doubler:


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

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



<关于你的第一个错误, int 是特殊的,从某种意义上说它也是一个函数。正如你指出的那样,你可以在枚举中使用一个基础类型约束,但是在这种情况下应该明确这个类型,所以不会有任何混淆:

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)

不幸的是,如果不使用 EnumToValue ,您仍然无法投射到 int C>。可能是编译器问题,或其他。也许EnumToValue的内部可以给出提示?

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?

这篇关于带Enum类型的F#类型约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆