Что такое унарный тип?

Я просматриваю раздел Высокородные типы и специальный полиморфизм школы Scala в Твиттере, и я не понимаю и нигде не могу найти ссылку на унарный тип. Вот контекст использования:

Например, в то время как «унарные типы» имеют такие конструкторы, как List[A], это означает, что мы должны удовлетворить один «уровень» переменных типа, чтобы создать конкретные типы (точно так же, как незатейливая функция должна быть предоставлена только один список аргументов, который должен быть вызван), тип более высокого порядка


person MrBouh    schedule 23.03.2017    source источник
comment
AFAIK, это не официальный термин. Думайте об этом как об унарной функции в пространстве типов, о типе, который имеет один аргумент типа, например List.   -  person n. 1.8e9-where's-my-share m.    schedule 23.03.2017
comment
спасибо, что вы имеете в виду под типовым пространством?   -  person MrBouh    schedule 23.03.2017
comment
Набор, коллекция или категория типов Scala, назовите их как хотите.   -  person n. 1.8e9-where's-my-share m.    schedule 23.03.2017


Ответы (2)


Это утверждение действительно не имеет смысла.

Во-первых, не существует такого понятия, как «унарный тип». Типы не имеют параметров, поэтому в этом нет смысла.

Существуют "конструкторы унарного типа", то есть конструкторы типов, которые имеют один параметр, например List[A]. Но это утверждение подразумевает, что все конструкторы типов, которые не являются унарными, относятся к более высокому типу, и это просто неверно. Например, Either[A, B] является двоичным (у него два параметра), но не более высокого порядка.

Конструктор типа, который имеет тип конструктор в качестве параметра или конструктор типа, который возвращает тип конструктор в качестве своего результата, тот является более высоким конструктор родственного типа. Точно так же, как функция с двумя аргументами не является автоматически высшим порядком, только функция, которая имеет параметр функции или возвращает функцию. (Примечание: в некоторых разделах математики функции называются «конструкторами значений», откуда и происходит название «конструктор типов», потому что так же, как функция принимает значения и производит значения, конструктор типов принимает типы и производит типы; конструктор типа подобен функции на уровне типа.)

Здесь есть одна загвоздка, такая же, как и с функциями: когда мы предполагаем, что все конструкторы типов являются унарными, тогда нам нужно использовать каррирование для представления конструкторов типов с более чем одним параметром, а в в этом смысле (и только в этом смысле!) все конструкторы не унарных типов автоматически также являются конструкторами типов более высокого порядка. Опять же, это похоже на функции: add ни в коем случае не является функцией высшего порядка, но если мы используем каррирование, мы представляем ее как функцию, которая принимает одно целое число и возвращает функцию, которая принимает второе целое число и возвращает целое число, что технически делает его функцией высшего порядка.

Но в Scala это не так: Scala может представлять конструкторы типов с несколькими параметрами без использования каррирования, поэтому конструкторы неунарных типов не имеют автоматически более высокого порядка.

Виды обозначаются аналогично типам, за исключением того, что мы просто пишем * вместо Type, потому что он не передает никакой информации: конструкторы типов всегда работают с типами, нет необходимости вводить Type везде. Итак, конструктор унарного типа, такой как List, имеет вид:

* → *

Конструктор двоичного типа, такой как Either, имеет вид:

(*, *) → *

Когда вы вынуждены представлять его с помощью каррирования, потому что ваш язык допускает только один параметр типа, тогда вид Either становится:

* →  * → *  // `→` is right-associative just as with function types, so this is 
* → (* → *) // which is higher-kinded

Конструктор типа Container со страницы, которую вы связали, имеет вид:

Container :: (* → *) → *

Итак, он принимает конструктор типа в качестве аргумента и возвращает тип. И это то, что делает его более родственным. Фактически, вы заметите, что Container на самом деле является одинарным! Требуется только один аргумент. Таким образом, заявление фактически содержит контрпример своему собственному утверждению. (И снова, это похоже на функции. Например, функция fix в прелюдии к Haskell имеет более высокий порядок, но унарна: она принимает только один аргумент, но этот аргумент является функцией.)

Причина, по которой это указывается конкретно в этом описании, заключается в том, что это неверно для некоторых других основных языков в области типизированных объектно-ориентированных языков, таких как Java или C♯. И Java, и C♯ не допускают конструкторы типов в качестве параметров или результатов конструкторов типов. Вы можете передать тип только конструктору типа, а результатом конструктора типа всегда будет тип. И Java, и C♯ не поддерживают типы более высокого порядка. Это делает Scala несколько особенным в этом отношении, и именно поэтому он указан специально на этой странице. (Конечно, в области типизированных функциональных языков в высокодобии нет ничего особенного.)

tl; dr резюме:

  • не существует такой вещи, как "унарный тип"
  • оператор объединяет арность конструкторов типов (количество параметров) с более высокой степенью (независимо от того, являются ли параметры и / или результаты типами или конструкторами типов)
  • неунарные конструкторы типов не обязательно должны быть высшими, например Either[A] :: (*, *) → *
  • конструкторы высших типов могут быть унарными, например Container :: (* → *) → *

В этом моем старом ответе есть дополнительная информация: Что такое «вид» в контексте систем типов? .

person Jörg W Mittag    schedule 23.03.2017
comment
Но * → * → * - это * → (* → *), который является более старшим (по виду результата, а не по типу аргумента). - person n. 1.8e9-where's-my-share m.; 23.03.2017
comment
Да, как я уже писал: как только вы ограничиваете себя конструкторами только унарных типов и используете каррирование для представления конструкторов не унарных типов, тогда все конструкторы не унарных типов становятся выше -родный по определению. Но они более высокородны * в том же смысле, что сложение двух чисел является функцией высшего порядка: это следствие искусственного ограничения арности, чтобы она всегда была ровно 1. - person Jörg W Mittag; 23.03.2017
comment
Я бы, может быть, назвал это искусственной доброжелательностью? Я не знаю, есть ли для этого термин? Опять же, легче говорить об этом в терминах функций, потому что это то, с чем люди, вероятно, более знакомы: в Scala add имеет тип (Int, Int) → Int, потому что Scala допускает более одного аргумента. В Haskell add имеет тип Int → ( Int → Int) просто потому, что нет другого способа его представить. (Ну, вы, конечно, могли бы использовать вместо этого двухкортежный кортеж, создавая таким образом тип (Int × Int) → Int.) Но, даже если add по необходимости является более высоким порядком в Haskell, вы, как правило, не вызываете ... - person Jörg W Mittag; 23.03.2017
comment
… Это функция высшего порядка, и если бы вас попросили привести пример функции высшего порядка, вы, вероятно, ответили бы map или flip, но не add. Имеет ли это смысл? - person Jörg W Mittag; 23.03.2017

Унарный - это еще один способ сказать "от арности". Функция с одним параметром называется унарной, функция с двумя параметрами - двоичной, функция с тремя параметрами - троичной и т. Д.

Тот же принцип применяется к типам. List[A] или Set[A], например, принимает один тип A для формирования нового правильного типа, тогда как Map[A, B] принимает два и называется конструктором двоичного типа.

Кстати, типы, которые абстрагируются от конструктора типа, называются типами более высокого порядка (например, Monad[F[_]])

person LMeyer    schedule 23.03.2017