titulos subtitulos paginas pagina numero enumerar como algunas f# discriminated-union

subtitulos - ¿Cómo enumerar una unión discriminada en F#?



como enumerar titulos y subtitulos en word (4)

¿Cómo puedo enumerar a través de los posibles "valores" de una unión discriminada en F #?

Quiero saber si hay algo como Enum.GetValues(Type) para uniones discriminadas, pero no estoy seguro de qué tipo de datos enumeraré. Me gustaría generar una lista o matriz de una unión discriminada con un elemento para cada opción.


Es difícil ver cómo esto podría funcionar sin tener también una instancia, ya que las uniones discriminatorias pueden tener valores.

Si tuvieras un tipo como este por ejemplo:

type Status = Success of string | Error of System.Exception | Timeout

¿Qué incluirías en tu matriz para el éxito o error en este caso?


Para extender ligeramente el ejemplo de Robert, incluso si no tiene una instancia de la unión discriminada, puede usar la reflexión F # para obtener la información sobre el tipo (como los tipos de los argumentos de casos individuales). Lo siguiente amplía el ejemplo de Robert y también imprime los tipos de argumentos:

open Microsoft.FSharp.Reflection let ty = typeof<option<int>> let cases = FSharpType.GetUnionCases ty printfn "type %s =" ty.FullName for case in cases do printf "| %s" case.Name let fields = case.GetFields() if fields.Length > 0 then printf " of" for fld in fields do printf " %s " fld.PropertyType.FullName printfn ""

Por ejemplo, para el tipo de option<int> , obtendrás (simplifiqué ligeramente la salida):

type Microsoft.FSharp.Core.FSharpOption`1[System.Int32] = | None | Some of System.Int32

Hay muchos usos interesantes para esta información; por ejemplo, puede generar un esquema de base de datos a partir de uniones F # o crear funciones que analicen XML en una unión discriminada (que describe la estructura). Hablé sobre la muestra de procesamiento XML en la conferencia GOTO a principios de este año .


Sí, F # tiene su propia capa de reflexión construida sobre la reflexión de .NET para ayudarlo a comprender los tipos que son específicos de F #, como discriminar uniones. Aquí está el código que le permitirá enumerar los casos de una unión:

open Microsoft.FSharp.Reflection type MyDU = | One | Two | Three let cases = FSharpType.GetUnionCases typeof<MyDU> for case in cases do printfn "%s" case.Name


Si su unión discriminada solo está formada por identificadores simples (en ningún caso se almacena ningún dato, esto podría ser lo que necesita: gist

open Microsoft.FSharp.Reflection module SimpleUnionCaseInfoReflection = // will crash if ''T contains members which aren''t only tags let Construct<''T> (caseInfo: UnionCaseInfo) = FSharpValue.MakeUnion(caseInfo, [||]) :?> ''T let GetUnionCaseInfoAndInstance<''T> (caseInfo: UnionCaseInfo) = (caseInfo, Construct<''T> caseInfo) let AllCases<''T> = FSharpType.GetUnionCases(typeof<''T>) |> Seq.map GetUnionCaseInfoAndInstance<''T>

#load "SimpleUnionCaseInfoReflection.fs" type Foos = Foo | Bar | Baz SimpleUnionCaseInfoReflection.AllCases<Foos> |> Seq.iter (fun (caseInfo, instance) ->printfn "name: %s instance: %O is Bar? : %b" caseInfo.Name instance (instance.Equals(Foos.Bar))) (* > name: Foo instance: FSI_0055+Foos is Bar? : false > name: Bar instance: FSI_0055+Foos is Bar? : true > name: Baz instance: FSI_0055+Foos is Bar? : false *)