Void в отличие от Unit
-
19-09-2019 - |
Вопрос
Я хотел бы понять, в чем разница между этими двумя концепциями программирования.Первый представляет собой отсутствие типа данных, а второй тип существует, но информации нет.Кроме того, я осознаю, что Unit возник из теоретической основы функционального программирования, но я до сих пор не могу понять, в чем удобство использования примитива unit (например, в программе F #).
Решение
Тип юнита просто делает все более регулярным.В какой-то степени каждую функцию в F# можно представить как принимающую один параметр и возвращающую один результат.Функции, которым не нужны никакие параметры, фактически принимают «единицу» в качестве параметра, а функции, которые не возвращают никаких результатов, возвращают в качестве результата «единицу».Это имеет множество преимуществ;во-первых, представьте, что в C# вам нужно как множество делегатов Func для представления функций различной арности, возвращающих значения, так и множество делегатов Action, которые не возвращают значений (потому что, например, Func<int,void>
недопустимо — void нельзя использовать таким образом, поскольку это не совсем «настоящий» тип).
Смотрите также Типы функций F#:развлечение с кортежами и каррированием
Другие советы
В функциональном программировании мы обычно говорим о сопоставлении входных данных с выходными.Это буквально означает сопоставление аргумента с его возвращаемым значением(ями).Но если что-то будет функцией в математическом/теоретико-категориальном смысле, оно должно вернуть что-нибудь.А void
value означает, что функция ничего не возвращает, что в данном случае бессмысленно.
unit
является функциональным ответом на void
.По сути, это тип только с одним значением, ()
.У него есть несколько применений, но вот одно простое.Допустим, у вас было что-то подобное в более традиционном императивном языке:
public static <T, U> List<U> map(List<T> in, Function<T, U> func) {
List<U> out = new ArrayList<U>(in.size());
for (T t : in) {
out.add(func.apply(t));
}
return out;
}
Это применяет конкретную функцию func
каждому элементу списка, создавая новый список func
тип вывода. Но что произойдет, если вы передадите функцию, которая просто печатает свои аргументы? У него не будет типа вывода, так что же вы можете указать для U
?
В некоторых языках передача такой функции приведет к поломке этого кода (например, в C#, где вы не можете присвоить void
к общему типу).Вам придется прибегнуть к обходным путям, таким как Action<T>
, который может стать неуклюжим.
Вот здесь и появилась концепция unit
Полезно: это является тип, но такой, который может принимать только одно значение.Это значительно упрощает такие вещи, как создание цепочек и композицию, а также значительно уменьшает количество особых случаев, о которых вам придется беспокоиться.