Что такое более высокий тип в Scala? - PullRequest
250 голосов
/ 06 июня 2011

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

  1. Тип с более высоким родом == Конструктор типа?

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

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

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

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

  2. Конструктор типа с более высоким типом ==, который принимает конструктор типа в качестве параметра типа?

    В статье Обобщение высшего рода вы можете читать

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

    , что говорит о том, что

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

    является типом с более высоким родом.

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

Ответы [ 4 ]

253 голосов
/ 21 июня 2011

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

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

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

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

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

Интерпретация первого порядка вышеуказанных характеристик абстракций:

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

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

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

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

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

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

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

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

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

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

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

                   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

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

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

94 голосов
/ 21 июня 2011

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

Типы с более высоким родом являются частью Scala с 2.5.

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

     trait Monad [M[_]]
    

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

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

    Type and  kind realtion, **derived** from (Изображение получено из Обобщения высшего рода )

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

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

    типСистема Java с другой стороны не поддерживает типы и, следовательно, не имеет типов «более высокого типа».

    Так что это должно быть видно на фоне системы поддержки типов.

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

     trait Iterable[A, Container[_]]
    

    с заголовком «Типы с более высокими типами», например, в Scalaдля универсальных программистов, раздел 4.3

    Это иногда вводит в заблуждение, потому что многие называют Container типом старшего типа , а не Iterable, но что более точно,

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

71 голосов
/ 06 июня 2011

Тип обычных типов, таких как Int и Char, экземплярами которых являются значения, равен *. Тип унарных конструкторов типа Maybe равен * -> *; конструкторы двоичного типа, такие как Either, имеют ( curried ), вид * -> * -> * и т. д. Вы можете просматривать типы типа 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: преобразует конструкторы унарного типа в ограничения класса типов
31 голосов
/ 06 июня 2011

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

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

Здесь Functor - это «тип высшего рода» (используемый в статье «Generics of the Higher Kind» ).Это не конкретный ("первого порядка") конструктор типа, такой как List (который абстрагируется только над собственными типами).Он абстрагируется от всех унарных («первого порядка») конструкторов типов (обозначаемых F[_]).

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

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

...