Dziś rano z kolei OCaml powitał mnie komunikatem
File "Database.ml", line 54, characters 17-25:
This pattern matches values of type punkt
but is here used to match values of type punkt
Bardzo zdziwiłem się widząc ten komunikat. I chyba nie znalazłbym błędu, gdybym nie widział podobnego błędu wcześniej. Troszkę starań i OCaml wypluje nam taki komunikat:
This expression has type t but is here used with type t
Jak zmusić OCamla do wyplucia takiego błędu? Opiszemy za chwilę. Na razie spróbujmy zrozumieć co tak na prawdę OCaml ma na myśli. Rozważmy następującą sesję ewaluatora:
# type typ1 = Konstruktor | Innykonstruktor;;W trzecim poleceniu do zdefiniowania typu "typ2" użyliśmy ponownie konstruktora "Konstruktor". Przesłoniliśmy w ten sposób konstruktor o tej samej nazwie z typu pierwszego. Nie będziemy mogli już z niego normalnie korzystać. Gdy użyjemy teraz w dowolnym miejscu konstruktora "Konstruktor" zostanie on potraktowany jako konstruktor z typu drugiego (a nie jako konstruktor typu pierwszego).
type typ1 = Konstruktor | Innykonstruktor
# Konstruktor;;
- : typ1 = Konstruktor
# type typ2 = Konstruktor | Jeszczeinnykonstruktor;;
type typ2 = Konstruktor | Jeszczeinnykonstruktor
# Konstruktor;;
- : typ2 = Konstruktor
# type t = Konstruktor of int;;Przeanalizujmy co tutaj się stało. W pierwszej linijce tworzymy nowy typ t. W drugiej linijce definiujemy funkcję, która jako argument bierze typ t - ten z pierwszej linijki (mniejsza o to co ta funkcja robi). W linijce trzeciej tworzymy nowy typ t (ma on nawet tą samą definicję co nasz pierwszy typ t - mimo to będzie traktowany jako nowy typ). Przesłaniamy w ten sposób pierwszy typ t. W linijce czwartej definiujemy wartość "osiem" używając konstruktora "Konstruktor". Jak wiemy z poprzedniego akapitu - będzie to wartość typu t zadeklarowanego w 3 linijce. Na koniec próbujemy wywołać funkcję od wartości "osiem", która jest typu t (zdefiniowanego w linijce 3) podczas gdy funkcja przyjmuje argumenty typu t (zdefiniowane w linijce pierwszej).
type t = Konstruktor of int
# let get_int a = match a with Konstruktor b -> b;;
val get_int : t -> int =
# type t = Konstruktor of int;;
type t = Konstruktor of int
# let osiem = Konstruktor 8;;
val osiem : t = Konstruktor 8
# get_int osiem;;
This expression has type t but is here used with type t
Brak komentarzy:
Prześlij komentarz