简体   繁体   中英

Strict generic enum conversion in F#

I want to write a function with signature int -> 'TEnum that will throw an exception in case the target enum don't contain an input value. Here's my first try:

let parseEnum<'TEnum when 'TEnum : enum<int>> (value : int) : 'TEnum =
    let enumType = typeof<'TEnum>
    if not <| Enum.IsDefined (enumType, value) then
        raise <| ArgumentException (sprintf "Invalid value of %A: %d" enumType value)

    enum value

The compiler shows me the following error message: "error FS0001: The declared type parameter 'TEnum' cannot be used here since the type parameter cannot be resolved at compile time" (I think that's because of the enum function that have an additional constraint).

Well, okay then, I understand the problem. I'll use statically resolved type parameter . Here's my second try:

let inline parseEnum2 (value : int) : ^TEnum =
    let enumType = typeof<^TEnum>
    if not <| Enum.IsDefined (enumType, value) then
        raise <| ArgumentException (sprintf "Invalid value of %A: %d" enumType value)

    enum value

But compiler still complains: "error FS3156: Unexpected token '>' or incomplete expression" at the line typeof<^TEnum> .

What am I doing wrong? How could I write this function?

You just need a space between the 'hat' sign ˆ and the < like this:

let enumType = typeof< ^TEnum>

In fact you don't need the hat, you can write:

open System
let inline parseEnum2 value : 'TEnum =
    let enumType = typeof<'TEnum>
    if not <| Enum.IsDefined (enumType, value) then
        raise <| ArgumentException (sprintf "Invalid value of %A: %d" enumType value)

    enum value

Because the static constraint is inferred automatically in this case, the only place when you really have to write the 'hat' is when writing the static constraint by hand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM