How to enumerate an enum/type in F#

前端 未结 7 1992
攒了一身酷
攒了一身酷 2021-01-11 09:43

I\'ve got an enumeration type defined like so:

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

is

相关标签:
7条回答
  • 2021-01-11 10:00

    To make it an enum you need to explicitly give values to each case, otherwise it's a union type:

    type tags = 
        | ART = 0
        | N = 1
        | V = 2
        | P = 3
        | NULL= 4
    let allTags = System.Enum.GetValues(typeof<tags>)
    
    0 讨论(0)
  • 2021-01-11 10:08

    You can use Enum.GetValues, which returns an Array of objects that you then have to downcast to integer values. (Note: I'm using Mono's F# implementation; maybe things are different with .NET.)

    Here are some functions I wrote to get a list of all enumeration values and to get the min and max values:

    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)
    
    0 讨论(0)
  • 2021-01-11 10:08
    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()
    
    0 讨论(0)
  • 2021-01-11 10:10

    Here is a complete example that prints information about any discriminated union. It shows how to get cases of the discriminated union and also how to get the fields (in case you needed them). The function prints type declaration of the given discriminated union:

    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>>)
    
    0 讨论(0)
  • 2021-01-11 10:13

    Use Enum.GetValues:

    let allTags = Enum.GetValues(typeof<tags>)
    
    0 讨论(0)
  • 2021-01-11 10:18

    How about:

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

    This has the advantage of providing a strongly typed list

    To use just do:

    let tagList = enumToList<tags>
    
    0 讨论(0)
提交回复
热议问题