generics - F# 具有 Enum 类型的类型约束

标签 generics enums f#

我想编写一个 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/

相关文章:

java - 如何使用将枚举传递给 DTO

spring-boot - 如何使用 Spring Boot 和 Cassandra 将枚举持久化为序数?

F# 多态类型

f# - 从 Fable.Remoting 返回异步值

Java 通配符通用,在 <? 上没有出现错误super String> 但否则错误为 "cannot be applied to Java.lang.String"

Java 泛型 : Returning object of generic class with type parameter that is a super of argument T

javascript - 如何在枚举上创建代理?

f# - 类型成员中的属性和 let 语句

java - 如何在 Java 中声明类型化类?

java - Java中类型删除的异常(exception)是什么?