2015-12-05 3 views
4

Я хочу написать функцию с сигнатурой int -> 'TEnum, которая будет генерировать исключение, если целевое перечисление не содержит входного значения. Вот моя первая попытка:Строгое преобразование enum enum в F #

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 

Компилятор показывает мне следующее сообщение об ошибке: «Ошибка FS0001: объявленный типа параметр„TEnum“не может быть использован здесь, так как параметр типа не может быть разрешен во время компиляции» (я думаю, это из-за функции enum, которая имеет дополнительное ограничение).

Ну, ладно, тогда я понимаю проблему. Я буду использовать statically resolved type parameter. Вот моя вторая попытка:

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 

Но компилятор все еще жалуется: «ошибка FS3156: Неожиданный маркер„>“или неполное выражение» на линии typeof<^TEnum>.

Что я делаю неправильно? Как я могу написать эту функцию?

ответ

6

Вам просто нужно пространство между «шляпой» знаком ˆ< и как это:

let enumType = typeof< ^TEnum> 

На самом деле вам не нужна шляпа, вы можете написать:

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 

Поскольку статическое ограничение автоматически выводится в этом случае, единственное место, когда вам действительно нужно писать «шляпу», - это при записи статического ограничения вручную.

Смежные вопросы