Что такое более высокий тип в Scala?

224

В Интернете вы можете найти следующее:

  • Конструктор более высокого типа == ==

    class AClass[T]{...} // For example, class List[T]
    

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

    Более высокие типы типов - это типы, которые принимают другие типы и создают новый тип

    Они, однако, также известны как конструктор типов. (Например, в Программирование в Scala).

  • Конструктор с более высоким типом == type, который принимает тип конструктора как параметр типа <

    В статье Дженерики более высокого сорта вы можете прочитать

    ... типы, которые абстрагируются от типов, которые абстрактны по типам ( "более высокие типы" )... "

    что предполагает, что

    class XClass[M[T]]{...} // or
    
    trait YTrait[N[_]]{...} // e.g. trait Functor[F[_]]
    

    - более высокий тип.

Поэтому, имея в виду это, трудно различить конструктор типов, конструктор с более высоким типом и конструктором типов, который принимает типы конструкторов как параметр типа, поэтому вопрос выше.

  • 0
    Добавлен Фанктор Ландея в качестве примера.
Теги:
generics
types
constructor

4 ответа

239
Лучший ответ

Позвольте мне восполнить некоторые из этих путаниц, подав некоторые сомнения. Мне нравится использовать аналогию с уровнем ценности, чтобы объяснить это, поскольку люди, как правило, более знакомы с ним.

Конструктор типа - это тип, который можно применить для аргументов типа для "построения" типа.

Конструктор значений - это значение, которое вы можете применить к аргументам значения для "построения" значения.

Конструкторы значений обычно называются "функциями" или "методами". Эти "конструкторы" также называются "полиморфными" (потому что их можно использовать для создания "материала" различной "формы" ) или "абстракций" (поскольку они абстрагируются от того, что меняется между различными полиморфными экземплярами).

В контексте абстракции/полиморфизма первый порядок относится к "единственному использованию" абстракции: вы абстрагируетесь по типу один раз, но сам этот тип не может абстрагироваться ни от чего. Генераторы Java 5 являются первоклассными.

Первой интерпретацией вышеприведенных характеристик абстракций являются:

Конструктор типа - это тип, который можно применить к соответствующим аргументам типа для "построения" соответствующего типа.

Конструктор значений - это значение, которое вы можете применить к соответствующим аргументам значения, чтобы "построить" правильное значение.

Чтобы подчеркнуть, что нет абстракции (я думаю, вы могли бы назвать этот "нулевой порядок", но я этого не видел), например значение 1 или тип String, мы обычно говорим что-то является "правильным" значением или типом.

Собственное значение "немедленно можно использовать" в том смысле, что оно не ждет аргументов (оно не абстрагируется над ними). Думайте о них как о ценностях, которые вы можете легко распечатать/проверить (сериализация функции - обман!).

Правильный тип - это тип, который классифицирует значения (включая конструкторы значений), конструкторы типов не классифицируют какие-либо значения (сначала они должны применяться к аргументам правильного типа для получения соответствующего типа). Чтобы создать экземпляр типа, необходимо (но недостаточно), чтобы он был правильным типом. (Это может быть абстрактный класс или класс, к которому у вас нет доступа.)

"Высший порядок" - просто общий термин, который означает многократное использование полиморфизма/абстракции. Это означает то же самое для полиморфных типов и значений. Конкретно, абстракция более высокого порядка абстрагируется над чем-то, что абстрагируется над чем-то. Для типов термин "высший сорт" является специальной версией более общего "высшего порядка".

Таким образом, более высокая версия нашей характеристики становится:

Конструктор типа - это тип, который можно применить для аргументов типа (правильные типы или конструкторы типов) для "построения" подходящего типа (конструктора).

Конструктор значений - это значение, которое вы можете применить к аргументам значения (правильные значения или конструкторы значений) для "построения" правильного значения (конструктор).

Таким образом, "высший порядок" просто означает, что когда вы говорите "абстрагирование над X", вы действительно это понимаете! X, который абстрагируется, не теряет собственных "прав абстракции": он может абстрагировать все, что он хочет. (Кстати, я использую глагол "abstract" здесь, чтобы означать: оставить что-то, что не является существенным для определения значения или типа, так что он может быть изменен/предоставлен пользователем абстракции в качестве аргумента.)

Вот несколько примеров (по мотивам вопросов Лутца по электронной почте) правильных значений и типов первого порядка и более высокого порядка:

                   proper    first-order           higher-order

values             10        (x: Int) => x         (f: (Int => Int)) => f(10)
types (classes)    String    List                  Functor
types              String    ({type λ[x] = x})#λ   ({type λ[F[x]] = F[String]})#λ

Если используемые классы были определены как:

class String
class List[T]
class Functor[F[_]]

Чтобы избежать косвенности посредством определения классов, вам нужно как-то выразить функции анонимного типа, которые не выражаются непосредственно в Scala, но вы можете использовать структурные типы без излишних синтаксических накладных расходов (требуется стиль на https://stackoverflow.com/users/160378/retronym afaik):

В некоторой гипотетической будущей версии Scala, которая поддерживает функции анонимного типа, вы можете сократить эту последнюю строку из примеров до:

types (informally) String    [x] => x              [F[x]] => F[String]) // I repeat, this is not valid Scala, and might never be

(В личной заметке я сожалею о том, что когда-либо говорил о "более высоких типах", они просто типа, когда все! Когда вам абсолютно необходимо устранить неоднозначность, я предлагаю сказать такие вещи, как "тип конструктора типа", "type член конструктора" или "псевдоним конструктора типа", чтобы подчеркнуть, что вы не говорите только о правильных типах.)

ps: Чтобы усложнить ситуацию, "полиморфный" неоднозначен по-другому, поскольку полиморфный тип иногда означает универсально квантифицированный тип, такой как Forall T, T => T, который является правильным типом, поскольку он классифицирует полиморфные значения (в Scala, это значение может быть записано как структурный тип {def apply[T](x: T): T = x})

Показать ещё 1 комментарий
90

(Этот ответ является попыткой украсить ответ Адриана мавра некоторой графической и исторической информацией.)

Более высокие типы типов являются частью Scala с 2,5.

  • До этого Scala, как Java до сих пор, не разрешалось использовать конструктор типов ( "generics" в Java), которые будут использоваться как введите параметр в конструктор типа. например.

     trait Monad [M[_]]
    

    было невозможно.

    В Scala 2.5 система типов была расширена за счет способности классифицировать типы на более высоком уровне (известный как полиморфизм конструктора типов). Эти классификации известны как виды.

    Изображение 6062 (Изображение получено из Generics of Higher Kind)

    В результате можно использовать конструктор типа (например, List) так же, как другие типы в позиции параметров типа конструкторов типов и т.д. они стали типами первого класса с Scala 2.5. (Подобно функциям, которые являются значениями первого класса в Scala).

    В контексте системы типов, поддерживающей более высокие типы, мы можем различайте соответствующие типы, такие как Int или List[Int] из типов первого порядка типа List и типов более высокого уровня, например Functor или Monad (типы, которые абстрагируются от типов, которые абстрактны по типам).

    Система типов Java с другой стороны не поддерживает виды и поэтому не имеет типов "высшего рода".

    Итак, это нужно видеть на фоне поддерживающей системы типов.

  • В случае Scala вы часто видите примеры конструктора типа типа

     trait Iterable[A, Container[_]]
    

    с заголовком "Более высокие типы", например. в Scala для родовых программистов, раздел 4.3

    Это иногда происходит с ошибкой, потому что многие относятся к Container как к более высокому типу, а не к Iterable, но что более точно,

    использование Container в качестве параметра конструктора типа более высокого типа (более высокого порядка) здесь Iterable.

60

kind обычных типов, таких как Int и Char, экземплярами которых являются значения, является *. Тип конструкторов типа унарного типа, таких как Maybe, * -> *; конструкторы двоичного типа, такие как Either, имеют (curries) kind * -> * -> * и т.д. Вы можете просматривать типы типа Maybe и Either как функции уровня типа: они берут один или несколько типов и возвращают тип.

Функция имеет более высокий порядок, если она имеет порядок больше 1, где порядок (неформально) содержит глубину вложенности слева от стрелок функции:

  • Заказ 0: 1 :: Int
  • Заказ 1: chr :: Int -> Char
  • Заказ 2: fix :: (a -> a) -> a, map :: (a -> b) -> [a] -> [b]
  • Заказ 3: ((A -> B) -> C) -> D
  • Заказ 4: (((A -> B) -> C) -> D) -> E

Итак, длинный рассказ, более высокий тип - это просто функция более высокого порядка на уровне уровня.

  • Заказ 0: Int :: *
  • Заказ 1: Maybe :: * -> *
  • Заказ 2: Functor :: (* -> *) -> Constraint -higher-kinded: преобразует конструкторы унитарного типа в ограничения типа класса
  • 0
    Спасибо за этот другой подход и точку зрения :-)
  • 0
    Хорошо, я понял, что тогда будет примером в Scala для (* ⇒ *) ⇒ * и (* ⇒ *) ⇒ (* ⇒ *)? Подойдет ли Функтор Ландеи в первую категорию, а точнее во вторую?
Показать ещё 4 комментария
28

Я бы сказал: более абстрактные теги более высокого типа над конструктором типа. Например. рассмотрим

trait Functor [F[_]] {
   def map[A,B] (fn: A=>B)(fa: F[A]): F[B]
}

Здесь Functor является "высшим сортным типом" (как используется в статье "Дженерики более высокого сорта" ). Это не конкретный конструктор типа ( "первого порядка" ) типа List (который абстрагируется только над собственными типами). Он абстрагирует все конструкторы типа унарного ( "первого порядка" ) (как обозначается F[_]).

Или выразить это по-другому: в Java у нас явно есть конструкторы типа (например, List<T>), но у нас нет "более высоких типов", потому что мы не можем их абстрагировать (например, мы не можем напишите интерфейс Functor, определенный выше - по крайней мере, не .

Термин "полиморфизм конструктора более высокого порядка (тип конструктора)" используется для описания систем, которые поддерживают "более высокие типы типов".

  • 0
    Это то, что я подумал, но, похоже, это противоречит ответу Джона, где «конструктор конкретного типа» уже является «типом с более высоким родом».
  • 3
    Да. Согласно ответу Джона (насколько я понимаю), List<T> в Java будет конструктором унарного типа, поскольку он явно имеет вид * -> * . Чего не хватает в ответе Джона, так это того, что вы должны иметь возможность абстрагироваться над «целым» (а не только над вторым * как в Java), чтобы назвать его типом с более высоким родом.
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню