Дивіться цю відповідь 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
тип Еріка, але вони все ще можуть бутиInteger
s,Double
S,Ratio Integer
S ... Haskell готовий зробити довільний вибір між числовими типами, але не для інших класів типів.