Вы можете найти следующее в Интернете:
Тип с более высоким родом == Конструктор типа?
class AClass[T]{...} // For example, class List[T]
Некоторые говорят, что это тип с более высоким родом, потому что он абстрагируется от типов, которые будут соответствовать определению.
Типы с более высоким родом - это типы, которые принимают другие типы и создают новый тип.
Они также известны как конструктор типов . (Например, в Программирование в Scala ).
Тип с более высоким родом == конструктор типа, который принимает конструктор типа в качестве параметра типа?
В статье « Генерика высшего рода» вы можете прочитать
... типы, которые абстрагируются над типами, которые абстрагируются над типами («типы с более высоким родом») ... "
что говорит о том, что
class XClass[M[T]]{...} // or trait YTrait[N[_]]{...} // e.g. trait Functor[F[_]]
является более родственным типом.
Таким образом, учитывая это, трудно различить конструктор типа , тип с более высоким родом и конструктор типа, который принимает конструкторы типа в качестве параметра типа , поэтому вопрос выше.
Ответы:
Позвольте мне восполнить некоторые из этих недоразумений, объясняя это неоднозначностью. Мне нравится использовать аналогию с уровнем стоимости, чтобы объяснить это, поскольку люди, как правило, лучше знакомы с ней.
Конструкторы значений обычно называются «функциями» или «методами». Эти «конструкторы» также называются «полиморфными» (потому что они могут использоваться для конструирования «вещей» различной «формы») или «абстракций» (поскольку они абстрагируются от того, что варьируется между различными полиморфными экземплярами).
В контексте абстракции / полиморфизма первый порядок относится к «одноразовому использованию» абстракции: вы абстрагируетесь над типом один раз, но сам этот тип не может абстрагироваться над чем-либо. Java 5 дженерики первого порядка.
Интерпретация первого порядка вышеуказанных характеристик абстракций:
Подчеркнем, что здесь нет абстракции (я думаю, вы могли бы назвать это «нулевым порядком», но я нигде не видел, чтобы это использовалось), например, значение
1
или типString
, мы обычно говорим, что это «правильное» значение или тип.Подходящее значение «сразу же можно использовать» в том смысле, что оно не ожидает аргументов (оно не абстрагируется от них). Думайте о них как о значениях, которые вы можете легко распечатать / проверить (сериализация функции обманывает!).
Правильный тип - это тип, который классифицирует значения (включая конструкторы значений), конструкторы типов не классифицируют никакие значения (их сначала нужно применить к аргументам правильного типа, чтобы получить правильный тип). Для создания экземпляра типа необходимо (но не достаточно), чтобы это был правильный тип. (Это может быть абстрактный класс или класс, к которому у вас нет доступа.)
«Высший порядок» - это просто общий термин, который означает многократное использование полиморфизма / абстракции. Это означает то же самое для полиморфных типов и значений. Конкретно, абстракция высшего порядка абстрагируется от чего-то, что абстрагируется от чего-то. Для типов термин «более высокий род» является специализированной версией более общего «высшего порядка».
Таким образом, версия нашей характеристики высшего порядка становится:
Таким образом, «высший порядок» просто означает, что когда вы говорите «абстрагируясь над X», вы действительно это имеете в виду!
X
, Что абстрагируется над не теряет свое «право абстракции»: оно может абстрагироваться от все она хочет. (Между прочим, я использую здесь глагол «абстрактный», чтобы означать: опустить что-то, что не является существенным для определения значения или типа, так что оно может быть изменено / предоставлено пользователем абстракции в качестве аргумента .)Вот несколько примеров (вдохновленных вопросами Лутца по электронной почте) правильных значений и типов первого и высшего порядка:
Где используемые классы были определены как:
Чтобы избежать косвенного определения классов, вам нужно как-то выразить функции анонимного типа, которые не могут быть выражены напрямую в Scala, но вы можете использовать структурные типы без слишком больших синтаксических издержек (
#λ
-style из-за https://stackoverflow.com). / users / 160378 / retronym afaik):В некоторой гипотетической будущей версии Scala, которая поддерживает функции анонимного типа, вы можете сократить эту последнюю строку из примеров до:
(Лично я сожалею, что когда-либо говорил о «типах с более высоким родом», в конце концов, это просто типы! Когда вам абсолютно необходимо устранить неоднозначность, я предлагаю сказать такие вещи, как «параметр конструктора типа», «член конструктора типа»). или «псевдоним конструктора типов», чтобы подчеркнуть, что речь идет не только о правильных типах.)
PS: чтобы еще больше усложнить ситуацию, «полиморфный» неоднозначен по-другому, так как полиморфный тип иногда означает универсально квантифицированный тип, такой как
Forall T, T => T
, который является правильным типом, поскольку он классифицирует полиморфные значения (в Scala это значение может быть записывается как структурный тип{def apply[T](x: T): T = x}
)источник
(Этот ответ является попыткой украсить ответ адрианских мавров некоторой графической и исторической информацией.)
Более старшие виды являются частью Scala с 2.5.
До этого Scala, как и Java до сих пор, не разрешал использовать конструктор типов («generics» в Java) для использования в качестве параметра типа для конструктора типов. например
не представилось возможным.
(Изображение получено из Дженерики высшего сорта )
Следствием этого является то, что конструктор типов (например
List
) может использоваться так же, как и другие типы в позиции параметра типа конструкторов типов, и поэтому они стали первоклассными типами начиная с Scala 2.5. (Подобно функциям, которые являются первоклассными значениями в Scala).В контексте системы типов, поддерживающей более высокие типы, мы можем различать собственные типы , типы, подобные
Int
илиList[Int]
от типов первого порядка, например,List
и типы более высокого типа, такие какFunctor
илиMonad
(типы, которые абстрагируются над типами, которые абстрагируются над типами).Система типов Java с другой стороны не поддерживает типы и, следовательно, не имеет типов «более высокого типа».
Так что это должно быть видно на фоне системы вспомогательных типов.
В случае Scala вы часто видите примеры конструктора типа, такого как
с заголовком «Типы с более высоким родом», например, в Scala для универсальных программистов, раздел 4.3
Это иногда missleading, потому что многие называют в
Container
качестве высшего kinded типа , а неIterable
, но что более точно,источник
Вид обычных типов , как
Int
иChar
, чьи экземпляры значение, является*
. Родов конструкторы одинарных типа какMaybe
IS* -> *
; конструкторы двоичного типа, такие какEither
( карри )* -> * -> *
и т. д. Вы можете просматривать типы какMaybe
иEither
как функции уровня типа: они принимают один или несколько типов и возвращают тип.Функция более высокого порядка, если она имеет порядок больше 1, где порядок (неформально) - глубина вложения слева от стрелок функции:
1 :: Int
chr :: Int -> Char
fix :: (a -> a) -> a
,map :: (a -> b) -> [a] -> [b]
((A -> B) -> C) -> D
(((A -> B) -> C) -> D) -> E
Итак, короче говоря, тип с более высоким родом - это просто функция высшего порядка на уровне типа.
Int :: *
Maybe :: * -> *
Functor :: (* -> *) -> Constraint
—higher-kinded: конвертирует конструкторы унарного типа в ограничения класса типовисточник
Functor
производит правильный тип (ну, черта, но та же идея)Functor[F[_]]
из конструктора типовF
.(* => *) => (* => *)
ли выразить конвертер типов в Scala? Если нет, на каком-либо другом языке?* ⇒ * ⇒ *
с карри очень полезно. Спасибо!(* ⇒ *) ⇒ (* ⇒ *)
также может быть написано(* ⇒ *) ⇒ * ⇒ *
. Это может быть выражено в Scala, какFoo[F[_], T]
. Этот тип типа (в Хаскеле)newtype Twice f a = Twice (f (f a))
(например,Twice Maybe Int
≅Maybe (Maybe Int)
,Twice [] Char
≅[[Char]]
) или что-то более интересное, например, свободная монадаdata Free f a = Pure a | Free (f (Free f a))
.Я бы сказал: тезисы более высокого типа над конструктором типов. Например рассмотреть
Вот
Functor
«тип с более высоким родом» (используемый в статье «Generics of the Higher Kind» ). Это не конкретный ("первого порядка") конструктор типаList
(который абстрагируется только над собственными типами). Он абстрагируется от всех унарных («первого порядка») конструкторов типов (как обозначеноF[_]
).Или, другими словами: в Java у нас есть конструкторы типов (например
List<T>
), но у нас нет «типов с более высоким родом», потому что мы не можем абстрагироваться над ними (например, мы не можем написатьFunctor
интерфейс, определенный выше - по крайней мере, не напрямую ).Термин «полиморфизм высших порядков (конструктор типов)» используется для описания систем, которые поддерживают «высшие родовые типы».
источник
List<T>
в Java был бы конструктор унарного типа, поскольку он явно имеет вид* -> *
. Чего не хватает в ответе Джона, так это того, что вы должны иметь возможность абстрагироваться над «целым» (а не только за секунду,*
как в Java), чтобы назвать его типом с более высоким родом.def succ(x: Int) = x+1
вводит «конструктор значений» (см. Мой другой ответ о том, что я имею в виду под этим)succ
(никто не назвал бы это значение succ (x: Int)). По аналогии,Functor
это (действительно более высокий род) тип, определенный в вашем ответе. Опять же , вы не должны относиться к нему какFunctor[F[_]]
(что ,F
что?_
Они не входят в комплект , к сожалению, синтаксический сахар для экзистенциалам мутит воды здесь делает?!F[_]
Коротка дляF[T forSome {type T}]
)Scala REPL предоставляет
:kind
команду, котораяНапример,
В них
:help
даны четкие определения, поэтому я думаю, что стоит опубликовать их здесь полностью (Scala 2.13.2).источник