Дивіться цю відповідь StackOverflow щодо виводу типу Go. Я сам не знайомий з Go, але виходячи з цієї відповіді, це здається односторонньою «типовою дедукцією» (запозичити деяку темологію C ++). Це означає, що якщо у вас є:
x := y + z
тоді тип xвиводиться, з'ясовуючи тип y + z, що для компілятора порівняно тривіально. Для цього типи yта zпотрібно знати апріорно : це можна зробити за допомогою анотацій типів або зробити висновок із призначених їм літералів.
Навпаки, більшість функціональних мов мають умовивід типу, який використовує всю можливу інформацію в межах модуля (або функції, якщо алгоритм виводу є локальним) для отримання типу змінних. Складні алгоритми висновків (наприклад, Хіндлі-Мілнер) часто включають певну форму об'єднання типів (трохи схожу на розв’язання рівнянь) за лаштунками. Наприклад, у Haskell, якщо ви пишете:
let x = y + z
то Haskell може вивести тип не тільки , xале також yі zпросто на підставі того , що ви виконуєте додавання на них. В цьому випадку:
x :: Num a => a
y :: Num a => a
z :: Num a => a
(Нижній регістр aтут позначає поліморфний тип , який часто називають "generics" іншими мовами, такими як C ++. Num a =>Частина є обмеженням, що вказує на те, що aпідтримка типу має певне поняття додавання.)
Ось більш цікавий приклад: комбінатор з фіксованою точкою, який дозволяє визначити будь-яку рекурсивну функцію:
let fix f = f (fix f)
Зауважте, що ніде ми не вказали тип f, а також не вказали тип fix, але компілятор Haskell може автоматично визначити, що:
f :: t -> t
fix :: (t -> t) -> t
Це говорить про те, що:
- Параметр
fповинен бути функцією від якогось довільного типу tдо одного типу t.
fixце функція, яка отримує параметр типу t -> tі повертає результат типу t.
x,y,zтака жNumтип Еріка, але вони все ще можуть бутиIntegers,DoubleS,Ratio IntegerS ... Haskell готовий зробити довільний вибір між числовими типами, але не для інших класів типів.