如何在 F# 中枚举枚举/类型

发布于 2024-08-20 06:40:00 字数 271 浏览 3 评论 0原文

我有一个像这样定义的枚举类型:

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

有没有办法在标签中执行 for ...

这是我收到的错误:

值、构造函数、命名空间或 类型标签未定义

I've got an enumeration type defined like so:

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

is there a way to do a for ... in tags do ?

This is the error that I'm getting:

The value, constructor, namespace or
type tags is not defined

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

笑脸一如从前 2024-08-27 06:40:00

怎么样:

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

这具有提供强类型列表的优点,

使用时只需执行以下操作:

let tagList = enumToList<tags>

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>
兮子 2024-08-27 06:40:00

使用 Enum.GetValues

let allTags = Enum.GetValues(typeof<tags>)

Use Enum.GetValues:

let allTags = Enum.GetValues(typeof<tags>)
屋顶上的小猫咪 2024-08-27 06:40:00

这是一个完整的示例,打印有关任何受歧视工会的信息。它展示了如何获取受歧视联合的案例以及如何获取字段(如果您需要它们)。该函数打印给定可区分联合的类型声明:

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>>)

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>>)
夏末的微笑 2024-08-27 06:40:00

要使其成为枚举,您需要显式地为每种情况赋予值,否则它是联合类型:

type tags = 
    | ART = 0
    | N = 1
    | V = 2
    | P = 3
    | NULL= 4
let allTags = System.Enum.GetValues(typeof<tags>)

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>)
如梦初醒的夏天 2024-08-27 06:40:00

罗伯特关于如何生成实际枚举并获取其案例的说法是正确的。如果您有真正的联合类型,则可以通过 Microsoft.FSharp.Reflection.FSharpType.GetUnionCases 函数获取案例。

Robert's right about how to generate an actual enum and get its cases. If you have a true union type, you can get the cases via the Microsoft.FSharp.Reflection.FSharpType.GetUnionCases function.

疾风者 2024-08-27 06:40:00

您可以使用 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)

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)
新人笑 2024-08-27 06:40:00

在 .Net 5 中,有一个 Enum.GetValues 的通用重载,它消除了强制转换的需要。

Enum.GetValues<T>()

In .Net 5 there is a generic overload of Enum.GetValues which eliminates the need for casting.

Enum.GetValues<T>()
兰花执着 2024-08-27 06:40:00
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()
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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文