Давайте посмотрим на аналогию: функции.В некоторых разделах математики функции называются конструкторами значений , потому что это то, что они делают: вы помещаете одно или несколько значений, и они создают новое значение из этих.
Конструкторы типовэто одно и то же, за исключением уровня типов: вы помещаете один или несколько типов, и они создают из них новый тип.В некотором смысле они являются функциями на уровне типов.
Теперь, по нашей аналогии: каков аналог вопроса, который вы задаете?Что ж, это так: «Могут ли конструкторы значений (т.е. функции) рассматриваться как значения в функциональных языках программирования?»
И ответ таков: это зависит от языка программирования.Теперь для функциональных языков программирования ответ «Да» почти для всех (если не для всех) из них.Это зависит от вашего определения, что такое «функциональный язык программирования».Некоторые люди определяют функциональный язык программирования как язык программирования, который имеет функции в качестве значений, поэтому ответ будет тривиально «Да» по определению.Но некоторые люди определяют функциональный язык программирования как язык программирования, который не допускает побочных эффектов, и на таком языке не обязательно верно, что функции являются значениями.
Самым известным примером может быть ДжонFP Бэкуса, из его оригинальной статьи Можно ли освободить программирование от стиля фон Неймана?- функциональный стиль и его алгебра программ .В FP есть иерархия «функциональных» вещей.Функции могут иметь дело только со значениями, а сами функции не являются значениями.Однако существует понятие «функционалы», которые являются «конструкторами функций», то есть они могут принимать функции (и также значения) в качестве входных данных и / или создавать функции в качестве выходных данных, но они не могут принимать функционалы в качестве входных данных и / или создавать их какoutput.
Итак, FP, возможно, является функциональным языком программирования, но он не имеет функций в качестве значений.
Примечание: функции в качестве значений также называются «функциями первого класса» и функциями, которыепринимать функции в качестве входных данных или возвращать их в качестве выходных, называются «функциями более высокого порядка».
Если мы рассмотрим некоторые типы:
1 :: Int
[1] :: List Int
add :: Int → Int
map :: (a → b, List a) → b
Вы можете видеть, что мы можем легко сказать: любойзначение, тип которого содержит стрелку, является функцией.Любое значение, тип которого содержит более одной стрелки, является функцией более высокого порядка.
Опять-таки, то же самое относится и к конструкторам типов, поскольку они действительно одно и то же, за исключением уровня типа.В некоторых языках конструкторы типов могут быть типами, в некоторых - нет.Например, в Java и C♯ конструкторы типов не являются типами.Например, у вас не может быть List<List>
в C♯.Вы можете записать тип List<List>
в Java, но это вводит в заблуждение, поскольку два List
означают разные вещи: первый List
является конструктором типа, второй List
является необработанный тип , так что на самом деле не использует конструктор типа в качестве типа.
Что эквивалентно нашему примеру типов выше?
Int :: Type
List :: Type ⇒ Type
→ :: (Type, Type) ⇒ Type
Functor :: (Type ⇒ Type) ⇒ Type
(Обратите внимание, как у нас всегда есть Type
? Действительно, мы имеем дело только с типами, поэтому обычно мы не пишем Type
, а вместо этого просто пишем *
, произносится "Тип"):
Int :: *
List :: * ⇒ *
→ :: (*, *) ⇒ *
Functor :: (* ⇒ *) ⇒ *
Итак, Int
- правильный тип, List
- конструктор типов, который принимает один тип и создает тип, →
(конструктор типа функции) принимает два типа и возвращает тип(предполагая только унарные функции, например, используя каррирование или передачу кортежей), и Functor
является конструктором типов, который сам принимает конструктор типов и возвращает тип.
Тезисы "type-types" называются виды .Как и в случае с функциями, все, что имеет стрелку, является конструктором типа, а все, что содержит более одной стрелки, является конструктором высшего рода .
AКак и в случае с функциями, некоторые языки допускают конструкторы типов с более высоким родом, а некоторые - нет.Два языка, которые вы упоминаете в своем вопросе: Scala и Haskell do , но, как уже упоминалось выше, Java и C♯ не делают.вопрос:
Итак, конструкторы типов также являются типами?
Не совсем, нет.По крайней мере, не на любом языке, о котором я знаю.Видите, хотя у вас могут быть конструкторы типов с более высоким родом, которые принимают конструкторы типов в качестве входных данных и / или возвращают их в качестве выходных данных, вы не можете иметь выражение или значение, или переменную, или параметр, у которого в качестве типа используется конструктор типа.Вы не можете иметь функцию, которая принимает List
или возвращает List
.Вы не можете иметь переменную типа Monad
.Но вы можете иметь переменную типа Int
.
Итак, очевидно, что между типами и конструкторами типов есть разница.