Посмотрите этот ответ 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здесь обозначает полиморфный тип , часто называемый «обобщением» в других языках, таких как 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 готов сделать произвольный выбор между числовыми типами, но не для других классов типов.