2015-12-29 10 views

Odpowiedz

4

Polimorficzny porównanie funkcja polega na rekurencyjnym badania struktury wartości, zapewniając całkowitą kolejność ad-hoc w wartości SML, używane do zdefiniowania równości strukturalny testowane przez polimorficzny = operatora.

Z definicji nie jest zdefiniowany dla funkcji i zamknięć, co zaobserwował @antron. Rekurencyjny charakter definicji oznacza, że ​​równość strukturalna nie jest zdefiniowana dla wartości zawierających funkcję lub zamknięcie. Ten charakter rekursywny oznacza również, że funkcja nie jest zdefiniowana na wartościach rekurencyjnych, jak wspomniano również przez @antron.

równość strukturalny, a więc porównać funkcji i operatorów porównania, nie jest świadomy niezmienników struktury i nie mogą być wykorzystane do porównania (łagodnie) zaawansowane struktury danych takie jak zestawy, Map HashTbls i tak dalej. Jeśli pożądane jest porównanie tych struktur, należy napisać wyspecjalizowaną funkcję, dlatego Set i Map definiują taką funkcję.

Przy definiowaniu własnych struktur, dobrą zasadą jest, aby odróżnić

  • konkretnych typów, które są zdefiniowane wyłącznie w kategoriach prymitywnych typów i innych konkretnych typów. Typów betonu nie należy używać w przypadku struktur, których przetwarzanie oczekuje pewnych niezmienników, ponieważ łatwo jest stworzyć dowolne wartości tego typu, rozbijając te niezmienniki. W przypadku tych typów odpowiednia jest polimorficzna funkcja porównania i operatory.

  • typy abstrakcyjne, których konkretna definicja jest ukryta. W przypadku tych typów najlepiej jest zapewnić wyspecjalizowaną funkcję porównawczą. Model mixture library definiuje numer compare mixin, który może być użyty do wyprowadzenia operatorów porównania z implementacji funkcji . Jego użycie jest zilustrowane w README.

5

to nie działa w przypadku grup funkcyjnych:

# compare (fun x -> x) (fun x -> x);; 
Exception: Invalid_argument "equal: functional value". 

Podobnie nie (zazwyczaj) działają dla innych rodzajów, których wartości mogą zawierać funkcje:

# type t = A | B of (int -> int);; 
type t = A | B of (int -> int) 
# compare A A;; 
- : int = 0 
# compare (B (fun x -> x)) A;; 
- : int = 1 
# compare (B (fun x -> x)) (B (fun x -> x));; 
Exception: Invalid_argument "equal: functional value". 

również robi” t (ogólnie) działają dla cyklicznych wartości:

# type t = {self : t};; 
type t = { self : t; } 
# let rec v = {self = v};; 
val v : t = {self = <cycle>} 
# let rec v' = {self = v'};; 
val v' : t = {self = <cycle>} 
# compare v v;; 
- : int = 0 
# compare v v';; 
(* Does not terminate. *) 

Tes Przypadki są również wymienione w documentation dlaw Pervasives.

+4

Również polimorficzne "porównaj" i "=" nie "działają" dla wartości, które mogą mieć różne reprezentacje, na przykład typy wynikające z zastosowania 'Set' lub' Map'. –

+0

To również nie działa dla obiektów. Porównuje unikalny numeryczny identyfikator każdego obiektu.Zatem porównanie dwóch obiektów, które są fizycznie odrębne, takie jak "porównaj (koniec obiektu) (koniec obiektu)", nigdy nie zwraca 0. –

+0

@PascalCuoq, MartinJambon: Ale to zależy od twojej definicji "pracy". Nigdy nie gwarantowali, że podąży za twoją koncepcją równości. Musi po prostu przestrzegać niektórych (nieokreślonych) spójnych porządków. – newacct

Powiązane problemy