2009-04-08 11 views
7

est-il un moyen de correspondance de motif sur les fonctions syndicales discriminés, par exemple: -modèle correspondant à une union discriminée

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 

Il est évident que ce code n'est pas valide F # comme DefaultTest accepte un paramètre de test de type plutôt que ' a -> Test. Y a-t-il un moyen d'atteindre ce sans en spécifiant une valeur pour l'union discriminée? En fin de compte, ce qui m'intéresse, c'est une fonction qui entre une fonction de type 'a -> Test et sorties Test (valeur par défaut' a).

Répondre

5

Je ne comprends pas ce que vous êtes après, mais cela aide-t-il?

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

Brillant. C'est exactement ce dont j'ai besoin! Je me sens très stupide maintenant ...! – ljs

+0

J'ai aussi trouvé A |> fun f -> Unchecked.defaultof <_> |> f être plutôt délicieux !!! – ljs

+0

Souhaitez-vous "A Unchecked.defaultof <_>" plus? – Brian

1

Cela pourrait éventuellement fonctionner lorsque tous les constructeurs avaient le même type d'argument, disons int. Ensuite, on pourrait

match de t 0 de
| A 0 -> ...
| B 0 -> ...

+0

Malheureusement, les types d'argument doivent pouvoir être différents ...! – ljs

3

Je ne sais pas ce que vous êtes après, mais quelque chose comme:

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 

peut travailler pour vous ...

+0

Vraiment excellente réponse, mais la réponse de Brian arrive à résoudre mon problème précis plus génériquement! – ljs

Questions connexes