Как перечислить enum / type в F # - PullRequest
       22

Как перечислить enum / type в F #

13 голосов
/ 02 февраля 2010

У меня тип перечисления определен так:

type tags = 
    | ART  = 0
    | N    = 1
    | V    = 2 
    | P    = 3
    | NULL = 4

есть ли способ сделать for ... in tags do?

Это ошибка, которую я получаю:

Значение, конструктор, пространство имен или тип tags не определен

Ответы [ 7 ]

8 голосов
/ 02 февраля 2010

Использование Enum.GetValues:

let allTags = Enum.GetValues(typeof<tags>)
6 голосов
/ 02 февраля 2010

Вот полный пример, который печатает информацию о любом дискриминационном объединении. В нем показано, как получить дела о дискриминированном союзе, а также как получить поля (если они вам нужны). Функция печатает объявление типа данного различаемого объединения:

open System
open Microsoft.FSharp.Reflection

let printUnionInfo (typ:Type) = 
  printfn "type %s =" typ.Name
  // For all discriminated union cases
  for case in FSharpType.GetUnionCases(typ) do
    printf "  | %s" case.Name
    let flds = case.GetFields()
    // If there are any fields, print field infos
    if flds.Length > 0 then 
      // Concatenate names of types of the fields
      let args = String.concat " * " [ for fld in flds -> fld.PropertyType.Name ] 
      printf " of %s" args
    printfn ""    

// Example
printUnionInfo(typeof<option<int>>)
3 голосов
/ 14 мая 2018

Как насчет:

let enumToList<'a> = (Enum.GetValues(typeof<'a>) :?> ('a [])) |> Array.toList

Преимущество заключается в предоставлении строго типизированного списка

Для использования просто сделайте:

let tagList = enumToList<tags>
3 голосов
/ 01 мая 2014

Вы можете использовать Enum.GetValues, который возвращает Array объектов, которые вам затем необходимо уменьшить до целых значений. (Примечание: я использую реализацию Mono F #; возможно, с .NET все по-другому.)

Вот некоторые функции, которые я написал, чтобы получить список всех значений перечисления и получить минимальное и максимальное значения:

open System

module EnumUtil =

    /// Return all values for an enumeration type
    let EnumValues (enumType : Type) : int list =
        let values = Enum.GetValues enumType
        let lb = values.GetLowerBound 0
        let ub = values.GetUpperBound 0
        [lb .. ub] |> List.map (fun i -> values.GetValue i :?> int) 

    /// Return minimum and maximum values for an enumeration type
    let EnumValueRange (enumType : Type) : int * int =
        let values = EnumValues enumType
        (List.min values), (List.max values)
2 голосов
/ 02 февраля 2010

Роберт прав в том, как генерировать фактическое перечисление и получать его дела. Если у вас есть настоящий тип объединения, вы можете получить дела через функцию Microsoft.FSharp.Reflection.FSharpType.GetUnionCases.

2 голосов
/ 02 февраля 2010

Чтобы сделать перечисление, вам нужно явно указать значения для каждого случая, в противном случае это тип объединения:

type tags = 
    | ART = 0
    | N = 1
    | V = 2
    | P = 3
    | NULL= 4
let allTags = System.Enum.GetValues(typeof<tags>)
0 голосов
/ 11 мая 2017
type Options = 
    | Exit          = 0
    | CreateAccount = 1

Console.WriteLine()
Console.WriteLine("Choose an option:")
let allOptions = Enum.GetValues(typeof<Options>)
for option in allOptions do
    if (option <> null) then
        Console.WriteLine(sprintf "%d: %s" (option :?> int) (option.ToString()))
let optionChosen = System.Console.ReadLine()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...