2012-04-26 12 views
5

Niech to typy =Jak zastosować funkcję do wariantu?

type intC = int;; 
type boolC = bool; 
type stringC = string;; 

type component = A of intC | B of boolC | C of stringC;; 

Jeśli chcesz zastosować funkcję typu a komponentu A, muszę systematycznie dekonstrukcji komponentu?

dla exemple zrobić mam zrobić:

let add comp = 
    match comp with 
    | A i -> Some (i + 2) (*only A interests me, I return i + 2*) 
    | _ -> None   (*otherwise I return nothing*) 

a następnie dla każdej funkcji na składnik A? Czy istnieje jakiś sposób na uniknięcie twojego zwolnienia?

Odpowiedz

4

To naprawdę zależy od rodzaju operacji, jaką wykonasz na swoich typach.

Rozwiązanie podane przez @nlucaroni jest w porządku, ale jeśli chcesz zrobić coś nieco bardziej ogólne (i złożonego) można stosować zapis trzymać swoje cząstkowe funkcje mapy:

type 'a component_m = { 
    a : intC -> 'a; 
    b : boolC -> 'a; 
    c : stringC -> 'a; 
} 

let map_component m = function 
    | A a -> m.a a 
    | B b -> m.b b 
    | C c -> m.c c 

let add = map_component { 
    a = (fun x -> Some (x + 2)); 
    b = (fun _ -> None); 
    c = (fun _ -> None); 
} 

Jeśli nie chce mieć do napisać funkcję (fun _ -> None) każdym razem, można również użyć wartości domyślne, które rozciągają:

let none = { 
    a = (fun _ -> None); 
    b = (fun _ -> None); 
    c = (fun _ -> None); 
} 

let add = map_component { none with a = fun x -> Some (x+2) } 

można robić te same rzeczy z funktorów ale moim zdaniem to będzie przesadą.

3

można przekazać wyższego rzędu-funkcji do funkcji, dokłada komponentu zniszczenie dla ciebie,

let apply_if_a f = function 
    | A i   -> Some (f i) 
    | (B _ | C _) -> None 

typ tego byłoby

val apply_if_a : (int -> 'a) -> component -> 'a option 

Jak widać, polimorficzny dla dowolnej funkcji zastosowanej do dowolnej wartości A. Poza tym większość ludzi unika trzymania wszystkiego, _ i zamiast tego jest wyczerpująca.

+0

Widzę; czy jest to standardowy sposób radzenia sobie z tym problemem? Czy możliwe byłoby uczynienie go jeszcze bardziej ogólnym za pomocą modułów? – codablank1

+0

To zależy od tego, co dane reprezentują. Nigdy nie musiałem robić czegoś takiego i zniszczyłem wszystkie elementy, ale zbyt często nie dekonstruowałem i miałem odpowiednie przypadki dla "B" i "C". – nlucaroni

Powiązane problemy