2015-12-23 11 views
9

Ostatnio dostałam kodOCaml - Co to jest typ niesłuszny?

List.fold_left (fun acc x -> raise x ; acc) 3 

jestem całkowicie w porządku z tym częściowego stosowania mającym wartość funkcjonalną> Lista typ exn -> int, a fakt, że daje ostrzeżenie nie dziwi . Ja,> jednak nie jest pewne co pół ostrzeżenia oznacza:

Warning 21: this statement never returns (or has an unsound type.) 

nie mogę rzeczywiście znaleźć żadnego odniesienia do tego ostrzeżenia, gdzie nie jest to wynikiem nie-powracającego oświadczeniu. Nawet strona man dla ocamlc wspomina jedynie o niepracujących instrukcjach dla tego ostrzeżenia, a warnings.ml odnosi się do niej po prostu jako Nonreturning_statement.

Jestem zaznajomiony z pojęciem solidności w odniesieniu do systemów typu, ale sama idea typu, który jest z natury niesłuszny, wydaje mi się dziwna.

Moje pytania to:

Co to jest typ niesłuszny? Jaka jest sytuacja, w której nietypowy typ pojawiłby się, gdy OCaml wydawałby ostrzeżenie, a nie zawodzi bardzo mocno?

Ktoś opublikował to pytanie i podczas pisania odpowiedzi został usunięty. Uważam, że to pytanie jest bardzo interesujące i warte uwagi. Proszę zwrócić uwagę, może masz kogoś, kto jest gotów pomóc :-(

+2

Uważam, że pytanie zostało usunięte, ponieważ było duplikatem http://stackoverflow.com/questions/31278561/avoid-the-warning-warning-21-this-statement-never-returns- or-hasan -unsound-t, gdzie ostrzeżenie zostało spowodowane przez użycie zewnętrznej (js_of_ocaml) funkcji z nieograniczonym typem wyniku - jak w twojej odpowiedzi poniżej. Podejrzewam, że pytający to właśnie dał mi +1 na zaakceptowaną odpowiedź. To prawda, że ​​ostrość jest nieco inna. – antron

+0

Byłem osobą, która zapytała/usunęła to; Właśnie zauważyłem (hehe) to. To, co powiedział @antron, właśnie dlatego go skasowałem. I tak, to +1 było ode mnie. ;) – Will

Odpowiedz

12

Jak Ostrzeżenie 21 jest zgłaszane

Najpierw pomyślmy funkcji, która zwraca niezwiązane 'a: Nie mam na myśli funkcję jak let id x = x tutaj ponieważ ma Typ 'a -> 'a i powrót typ 'a odnosi się do wejścia. mam na myśli funkcje jak raise : exn -> 'a i exit : int -> 'a.

funkcje te zwracają niezwiązane 'a są uważane nigdy wracać. Od rodzaju 'a (dokładniej forall 'a. 'a) nie ma obywatel. Jedyne, co mogą zrobić funkcje, to zamknięcie programu (wyjście lub podniesienie wyjątku) lub wpadanie w nieskończoną pętlę: let rec loop() = loop().

Ostrzeżenie 21 jest wymienione, gdy typ oświadczenia to 'a. (Faktycznie istnieje inny stan, ale ja po prostu pominąć dla uproszczenia). Na przykład,

# loop(); print_string "end of the infinite loop";; 
Warning 21: this statement never returns (or has an unsound type.) 

To jest głównym celem ostrzeżenia 21. Następnie, co jest druga połowa?

"Unsound typu"

Warning 21 można zgłaszać nawet jeżeli oświadczenie zwrotów coś rzeczywiście. W tym przypadku komunikat ostrzegawczy sugeruje, że instrukcja ma typ niesłuszny.

Dlaczego złodziej? Ponieważ wyrażenie zwraca wartość typu forall 'a. 'a, która nie ma obywatela. Łamie podstawę teorii typu, od której zależy OCaml.

W SML, nie kilka sposobów, aby napisać wyraz z takiego rodzaju chorej:

Zastosowanie Obj.magic. To układ śrub typu zatem można napisać wyrażenie typu 'a która zwraca:

(Obj.magic 1); print_string "2" 

Zastosowanie external. Tak samo jak Obj.magic można podać dowolny typ do jakichkolwiek wartości zewnętrznych i funkcji:

external crazy : unit -> 'a = "%identity" 
let f() = crazy() (* val f : unit -> 'a *) 
let _ = f(); print_string "3" 

Dla systemu typu OCaml, niemożliwe jest, aby odróżnić zakaz powracających wyrażeń i zwrotów z niewłaściwych typów. Dlatego nie może wykluczyć rzeczy niesłusznych jako błędów. Śledzenie definicji stwierdzenia, że ​​oświadczenie ma charakter niesłuszny, jest również niemożliwe i kosztuje dużo, nawet jeśli jest to możliwe.

+1

Dobra odpowiedź. Dla kompletności, możesz chcieć wspomnieć o demarshalling ('input_value' i' Marshal.from_ * ') jako funkcje unsound. (w rzeczywistości twierdzę, że są one bardziej użyteczne niż "Obj.magic", szczególnie dla kogoś, kto nie jest ekspertem w systemach typu). – Virgile