Wnioskowanie o typie Hindleya-Milnera stosuje się w systemach typu Hindley-Milner, ograniczenie systemów typu System-F. Interesującą cechą systemów typu HM jest to, że mają parametryczny polimorfizm (inaczej generyczne). Jest to jedna z największych funkcji systemu typów, której Golang odmawia.
Przy tym frustrującym ograniczeniu wnioskowanie typu HM jest niemożliwe. Spójrzmy na nietypowy kod:
func f(a) {
return a.method()
}
Jaki to rodzaj f
? Możemy zauważyć, że a
musi mieć metodę, więc możemy użyć anonimowego interfejsu: func f(a interface { method() ??? }) ???
. Nie mamy jednak pojęcia, jaki jest typ zwrotu. Za pomocą zmiennych typu możemy zadeklarować typ jako
func f[T](a interface{ method() T }) T
Jednak Go nie ma zmiennych typu, więc to nie zadziała. Chociaż niejawne interfejsy ułatwiają niektóre aspekty wnioskowania o typie, nie mamy obecnie sposobu na znalezienie typu zwracanego wywołania funkcji. System HM wymaga, aby wszystkie funkcje były deklarowane, a nie sugerowane, a każda nazwa może mieć tylko jeden typ (podczas gdy metody Go mogą mieć różne typy w różnych interfejsach).
Zamiast tego Go wymaga, aby funkcje były zawsze w pełni deklarowane, ale zezwala zmiennym na używanie wnioskowania typu. Jest to możliwe, ponieważ prawa strona przypisania variable := expression
ma już znany typ w tym momencie programu. Tego rodzaju wnioskowanie o typach jest proste, poprawne i liniowe.
- Typ zmiennej jest natychmiast znany w punkcie deklaracji, podczas gdy wnioskowanie HM musi najpierw potencjalnie sprawdzić typ całego programu. Ma to również zauważalny wpływ na jakość komunikatów o błędach.
- Metoda wnioskowania typu Go zawsze wybierze najbardziej specyficzny typ zmiennej, w przeciwieństwie do HM, który wybiera najbardziej ogólny typ. To działa czysto z podsieciami, nawet z niejawnymi interfejsami Go.
map
, takich jakfilter
, ireduce
wszystkie są niewyrażalne w obrębie bardzo ograniczonego Go system typów.gengen
igonerics