2009-04-08 12 views
7

Esiste un modo per pattern matching sulle funzioni sindacali discriminati, ad esempio: -pattern matching su un'unione discriminata

type Test = 
    | A of string 
    | B of int 
    | C of char 

let DefaultTest t = 
    match t with 
    | A(_) -> A(null) 
    | B(_) -> B(0) 
    | C(_) -> C('\u0000') 

let a = A |> DefaultTest 

Ovviamente questo codice non è valido F # come DefaultTest accetta un parametro di tipo di prova, piuttosto che ' a -> Test. C'è un modo per raggiungere questo senza specificando un valore per l'unione discriminata?

Quello che sto cercando, in definitiva, è una funzione che immette una funzione di tipo 'a -> Test e output Test (valore predefinito di' a).

risposta

5

Annunciare la mia non è chiaro quello che sei dopo, ma questo aiuta?

type Foo = 
    | A of int 
    | B of string 

let CallWithDefault f = 
    let x = Unchecked.defaultof<_> 
    f x 

let defaultA = CallWithDefault A  
let defaultB = CallWithDefault B  
printfn "(%A) (%A)" defaultA defaultB 
+0

Brillante. Questo è esattamente ciò di cui ho bisogno! Mi sento molto stupido ora ...! – ljs

+0

Ho anche trovato A |> fun f -> Unchecked.defaultof <_> |> f per essere piuttosto buonissimo !!! – ljs

+0

Vorresti "Un Unchecked.defaultof <_>" di più? – Brian

1

Questo potrebbe funzionare quando tutti i costruttori hanno lo stesso tipo di argomento, ad esempio int. allora si potrebbe

partita t 0 di
| A 0 -> ...
| B 0 -> ...

+0

Sfortunatamente i tipi di argomento devono essere in grado di essere diversi ...! – ljs

3

Non sei sicuro di quello che stai dopo, ma qualcosa di simile:

let DefaultTest (t :obj) = 
    match t with 
    | :? (string->Test) as a -> Some (a null) 
    | :? (int -> Test) as b -> Some (b 0) 
    | :? (char -> Test) as c -> Some (c '\u0000') 
    | _ -> Option.None 

potrebbe funzionare per voi ...

+0

Risposta davvero eccellente, comunque la risposta di Brian capita di risolvere il mio problema preciso in modo più generico! – ljs