Zobacz tę odpowiedź StackOverflow dotyczącą wnioskowania o typie Go. Sam nie jestem zaznajomiony z Go, ale na podstawie tej odpowiedzi wydaje się, że jest to jednokierunkowa „dedukcja typu” (pożyczyć trochę teminologii w C ++). Oznacza to, że jeśli masz:
x := y + z
następnie typ x
jest wydedukowany przez ustalenie typu y + z
, co jest stosunkowo trywialną rzeczą dla kompilatora. Aby to zrobić, rodzaje y
i z
muszą być z góry znane : można tego dokonać za pomocą adnotacji typu lub wywnioskować z przypisanych im literałów.
Natomiast większość języków funkcjonalnych ma wnioskowanie typu, które wykorzystuje wszystkie możliwe informacje w module (lub funkcji, jeśli algorytm wnioskowania jest lokalny), aby wyprowadzić typ zmiennych. Skomplikowane algorytmy wnioskowania (takie jak Hindley-Milner) często wiążą się z pewną formą unifikacji typów (trochę jak rozwiązywanie równań) za kulisami. Na przykład w Haskell, jeśli napiszesz:
let x = y + z
wtedy Haskell może wywnioskować ten typ nie tylko, x
ale także y
i z
po prostu na podstawie tego, że wykonujesz na nich dodawanie. W tym przypadku:
x :: Num a => a
y :: Num a => a
z :: Num a => a
(Mała litera a
tutaj oznacza typ polimorficzny , często nazywany „ogólnymi” w innych językach, takich jak C ++. Num a =>
Część jest ograniczeniem wskazującym, że a
obsługa typów ma pewne pojęcie dodawania).
Oto bardziej interesujący przykład: kombinator stałoprzecinkowy, który umożliwia zdefiniowanie dowolnej funkcji rekurencyjnej:
let fix f = f (fix f)
Zauważ, że nigdzie nie podaliśmy typu f
ani nie podaliśmy typu fix
, jednak kompilator Haskell może automatycznie stwierdzić, że:
f :: t -> t
fix :: (t -> t) -> t
To mówi, że:
- Ten parametr
f
musi być funkcją od dowolnego dowolnego typu t
do tego samego typu t
.
fix
to funkcja, która odbiera parametr typu t -> t
i zwraca wynik typu t
.
x
,y
,z
są takie sameNum
typ Eric, ale nadal mogą być oneInteger
s,Double
s,Ratio Integer
s ... Haskell jest skłonny do arbitralnego wyboru typów liczbowych, ale nie dla innych typeclasses.