Введение

Тип, допускающий только одно значение – понятие, используемое в компьютерном программировании и теории типов. В области математической логики и информатики, известной как теория типов, унитарный тип (или тип единицы) – это тип, который допускает только одно значение (и, следовательно, не может нести никакой информации). Носителем (подлежащим множеством), связанным с унитарным типом, может быть любое одноэлементное множество. Между любыми двумя такими множествами существует изоморфизм, поэтому обычно говорят об унитарном типе, не вдаваясь в детали его значения. Также унитарный тип можно рассматривать как тип 0-кортежей, то есть произведение по пустому множеству типов. Унитарный тип является терминальным объектом в категории типов и типизированных функций. Его не следует путать с нулевым или пустым типом, который не допускает никаких значений и является начальным объектом в этой категории. Аналогично, булев тип – это тип с двумя значениями. Унитарный тип реализован в большинстве функциональных языков программирования. Тип `void`, используемый в некоторых императивных языках программирования, выполняет некоторые его функции, но из-за того, что его подлежащее множество пусто, он имеет определенные ограничения (как подробно описано ниже).

В языках программирования

Несколько языков программирования предоставляют тип единицы для указания типа результата функции с единственной целью вызвать побочный эффект и тип аргумента функции, которая не требует аргументов. В Haskell, Rust и Elm тип единицы называется `()` и его единственное значение также `()`, отражая интерпретацию 0-тупла. В потомках ML (включая OCaml, Standard ML и F#) тип называется `unit`, но значение записывается как `()`. В Scala тип единицы называется `Unit`, а его единственное значение записывается как `()`. В Common Lisp тип, названный `nil`, является типом единицы, который имеет одно значение, а именно символ `nil`. Это не следует путать с типом `t`, который является нижним типом. В Python есть тип, называемый `NoneType`, который позволяет использовать единственное значение `None`. В дополнительных статических аннотациях типа Python этот тип представлен как `None`. В Swift тип единицы называется `Void` или `()`, и его единственное значение также `()`, отражая интерпретацию 0-тупла. В Java тип единицы называется `Void`, и его единственное значение — `null`. В Go тип единицы записывается как `struct{}` и его значение — `struct{}{}`. В PHP тип единицы называется `null`, единственное значение которого — `NULL`. В JavaScript `null` (его единственное значение — `null`) и `undefined` (его единственное значение — `undefined`) являются встроенными типами единицы. В Kotlin `Unit` — это синглтон с единственным значением: объект `Unit`. В Ruby `nil` — единственный экземпляр класса `NilClass`. В C++ тип `std::monostate` был добавлен в C++17. До этого можно определить тип пользовательской единицы, используя пустую структуру, такую как `struct empty{};`.

Тип пустого места в качестве типа единицы

В C, C++, C# и D, `void` используется для обозначения функции, которая не возвращает никакого полезного значения, или функции, которая не принимает аргументов. Тип unit в C концептуально похож на пустую структуру, однако структура без членов не разрешена спецификацией языка C (в C++ это допустимо). Вместо этого `void` используется для имитации некоторых, но не всех свойств типа unit, как подробно описано ниже. Как и большинство императивных языков, C допускает функции, не возвращающие значение; они объявляются с типом возвращаемого значения `void`. Такие функции в других императивных языках, например, в Паскале, называются процедурами, где между функциями и процедурами делается синтаксическое, а не типовое различие.

Различие в хранении

Второе заметное отличие состоит в том, что тип void является специальным и не может быть сохранен в типе записи, то есть в структуре или классе в C/C++. В отличие от этого, тип unit может храниться в записях в функциональных языках программирования, то есть он может использоваться как тип поля; вышеуказанная реализация типа unit в C++ также может быть сохранена. Хотя это может показаться бесполезной возможностью, она позволяет, например, элегантно реализовать множество как отображение на тип unit; при отсутствии типа unit, множество все равно можно реализовать таким образом, сохраняя некоторое произвольное значение другого типа для каждого ключа.