Вывод типа
В этом разделе описывается, как компилятор F# определяет типы значений, переменных, параметров и возвращаемых значений.
Вывод типов в целом
Идея вывода типа заключается в том, что не нужно указывать типы конструкций F#, за исключением случаев, когда компилятор не может окончательно выводить тип. Опущение явных сведений о типе не означает, что F# является динамически типизированным языком или что значения в F# слабо типизированны. F# является статически типизированным языком, что означает, что компилятор выводит точный тип для каждой конструкции во время компиляции. Если для компилятора недостаточно сведений о типах каждой конструкции, необходимо указать дополнительные сведения о типе, как правило, путем добавления явных заметок типов где-то в коде.
Вывод типов параметров и возвращаемых значений
В списке параметров не нужно указывать тип каждого параметра. И тем не менее, F# является статически типизированным языком, поэтому каждое значение и выражение имеет определенный тип во время компиляции. Для тех типов, которые не указаны явным образом, компилятор вводит тип в зависимости от контекста. Если тип не указан в противном случае, он выводится как универсальный. Если в коде используется несогласованное значение, таким образом, что ни один выводимый тип не удовлетворяет всем использования значения, компилятор сообщает об ошибке.
Возвращаемый тип функции определяется типом последнего выражения в функции.
Например, в следующем коде типы параметров и b
возвращаемый тип будут выводитьсяint
, так как литерал 100
имеет типint
.a
let f a b = a + b + 100
Вы можете повлиять на вывод типов, изменив литералы. Если сделать это 100
uint32
путем добавления суффиксаu
, типов a
, b
а возвращаемое значение выводится.uint32
Вы также можете влиять на вывод типов с помощью других конструкций, которые подразумевают ограничения на тип, такие как функции и методы, которые работают только с определенным типом.
Кроме того, можно применить явные заметки типа к параметрам функции или метода или переменным в выражениях, как показано в следующих примерах. Ошибки приводят к возникновению конфликтов между различными ограничениями.
// Type annotations on a parameter.
let addu1 (x : uint32) y =
x + y
// Type annotations on an expression.
let addu2 x y =
(x : uint32) + y
Вы также можете явно указать возвращаемое значение функции, предоставив заметку типа после всех параметров.
let addu1 x y : uint32 =
x + y
Распространенный случай, когда заметка типа полезна для параметра, заключается в том, что параметр является типом объекта и требуется использовать элемент.
let replace(str: string) =
str.Replace("A", "a")
Автоматическое обобщение
Если код функции не зависит от типа параметра, компилятор считает, что этот параметр является универсальным. Это называется автоматической обобщением, и это может быть мощная помощь в написании универсального кода без повышения сложности.
Например, следующая функция объединяет два параметра любого типа в кортеж.
let makeTuple a b = (a, b)
Тип определяется как должен быть
'a -> 'b -> 'a * 'b
Дополнительная информация
Вывод типов подробно описан в спецификации языка F#.