quiero añadir otra solución que funciona con las cotizaciones para cada caso de unión, basado en el desco proporcionado. Aquí va:
open Microsoft.FSharp.Quotations.Patterns
open Microsoft.FSharp.Reflection
let rec isUnionCase = function
| Lambda (_, expr) | Let (_, _, expr) -> isUnionCase expr
| NewTuple exprs ->
let iucs = List.map isUnionCase exprs
fun value -> List.exists ((|>) value) iucs
| NewUnionCase (uci, _) ->
let utr = FSharpValue.PreComputeUnionTagReader uci.DeclaringType
box >> utr >> (=) uci.Tag
| _ -> failwith "Expression is no union case."
Definido de esta manera, isUnionCase funciona como desco ha demostrado, pero incluso en los casos del sindicato que están vacíos o tienen más de un valor. También puede ingresar una tupla de casos de unión separados por comas. Considere esto:
type SomeType =
| SomeCase1
| SomeCase2 of int
| SomeCase3 of int * int
| SomeCase4 of int * int * int
| SomeCase5 of int * int * int * int
let list =
[
SomeCase1
SomeCase2 1
SomeCase3 (2, 3)
SomeCase4 (4, 5, 6)
SomeCase5 (7, 8, 9, 10)
]
list
|> List.filter (isUnionCase <@ SomeCase4 @>)
|> printfn "Matching SomeCase4: %A"
list
|> List.filter (isUnionCase <@ SomeCase3, SomeCase4 @>)
|> printfn "Matching SomeCase3 & SomeCase4: %A"
El primer isUnionCase que proporcioné solo funcionó para verificaciones de casos individuales. Más tarde agregué el control de expresión para NewTuple y pensé que te gustaría. Solo asegúrese de que si altera el código, las precomputaciones aún funcionan, por eso iucs
se define fuera de la función anónima devuelta.
(ligeramente OT) Esto me recuerda, ya es hora de que [el resaltado de código sea compatible con F #] (http://meta.stackexchange.com/questions/58934/hight-time-for-code-highlighting-f-snippets) (!) – Abel
Ver http://meta.stackexchange.com/questions/981/syntax-highlighting-hints no hay resaltado específico de idioma en SO. – Brian