Rozważmy typ t
i dwie zmienne x,y
typu t
.Czy porównać pracę dla wszystkich typów?
Czy połączenie compare x y
będzie ważne dla dowolnego typu t
? Nie mogłem znaleźć żadnego kontrprzykładu.
Rozważmy typ t
i dwie zmienne x,y
typu t
.Czy porównać pracę dla wszystkich typów?
Czy połączenie compare x y
będzie ważne dla dowolnego typu t
? Nie mogłem znaleźć żadnego kontrprzykładu.
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.
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
.
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'. –
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. –
@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