mam problemy ze zrozumieniem letrec definicję systemu HM, który jest podany na Wikipedii, tutaj: https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system#Recursive_definitionsPrawidłowa forma letrec w systemie typu Hindley-Milner?
Dla mnie zasada przekłada się mniej więcej z następującym algorytmem:
- typy wywnioskować na wszystko w część
letrec
definicja- przypisać zmienne typu tymczasowe do każdego zdefiniowanego identyfikatora
- rekurencyjnie przetwarza wszystkie definicje z tymczasowych typów
- w parach, ujednolicenie wyników z oryginalnych zmiennych tymczasowych
- blisko (z
forall
) to wywnioskować typy, dodaj je do podstawy (kontekst) i wnioskować rodzajów części wypowiedzi z nim
mam problem z programem jak to:
letrec
p = (+) --has type Uint -> Uint -> Uint
x = (letrec
test = p 5 5
in test)
in x
zachowanie ja obserwując się następująco:
- definicja
p
dostaje typu CZASOWAa
- definicja
x
dostaje jakąś tymczasową typ też, ale to jest poza naszym zakresem teraz - w
x
, definicjatest
dostaje tymczasowy typut
p
Pobiera tymczasowy typa
z zakresu, przy użyciu reguły HM dla zmiennej(f 5)
jest przetwarzany przez regułę HM dla aplikacji, wynikowy typ tob
(i unifikujacą (a
łączy zUint -> b
)((p 5) 5)
zostanie przetworzona przez tej samej zasady, co prowadzi do większej liczby unifikacji i typuc
,a
się w wyniku łączy zUint -> Uint -> c
- teraz, test zostaje zamknięty typu
forall c.c
- zmienna test
in test
dostaje instancję typu (lubforall c.c
) ze zmiennymi świeżych, accrodingly z zasadą HM do zmiennej, w wynikutest :: d
(który jest zjednoczony ztest::t
tuż) - Powstały
x
skutecznie wpisaćd
(lubt
, w zależności od nastroju unifikacji)
problem: x
powinien oczywiście mieć typ Uint
, ale nie widzę sposób tych dwóch może kiedykolwiek ujednolicenia produkować typ. Następuje utrata informacji, gdy typ test
zostaje zamknięty i ponownie instancja, że nie jestem pewien, jak pokonać lub połączyć się z zastąpieniami/unifikacjami.
Każdy pomysł, w jaki sposób należy poprawić algorytm, aby prawidłowo pisać poprawnie?Czy jest to własność systemu HM i po prostu nie wpisuje takiego przypadku (w co wątpię)?
Zauważ, że byłoby to całkowicie w porządku ze standardem let
, ale nie chciałem zaciemniać przykładu rekurencyjnymi definicjami, które nie mogą być obsługiwane przez let
.
góry dzięki