~~~~~~~~~~~~~~~~~~~~ Arc.Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~ 
Номер скриншота №:
✰ 479815E005A20BBC64C923A50BE596C7__1700472420 ✰
Заголовок документа оригинал.:
✰ Intersection type - Wikipedia ✰
Заголовок документа перевод.:
✰ Тип перекрестка — Википедия ✰
Снимок документа находящегося по адресу (URL):
✰ https://en.wikipedia.org/wiki/Intersection_type ✰
Адрес хранения снимка оригинал (URL):
✰ https://arc.ask3.ru/arc/aa/47/c7/479815e005a20bbc64c923a50be596c7.html ✰
Адрес хранения снимка перевод (URL):
✰ https://arc.ask3.ru/arc/aa/47/c7/479815e005a20bbc64c923a50be596c7__translat.html ✰
Дата и время сохранения документа:
✰ 24.06.2024 07:17:23 (GMT+3, MSK) ✰
Дата и время изменения документа (по данным источника):
✰ 20 November 2023, at 12:27 (UTC). ✰ 

~~~~~~~~~~~~~~~~~~~~~~ Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~~ 
Сервисы Ask3.ru: 
 Архив документов (Снимки документов, в формате HTML, PDF, PNG - подписанные ЭЦП, доказывающие существование документа в момент подписи. Перевод сохраненных документов на русский язык.)https://arc.ask3.ruОтветы на вопросы (Сервис ответов на вопросы, в основном, научной направленности)https://ask3.ru/answer2questionТоварный сопоставитель (Сервис сравнения и выбора товаров) ✰✰
✰ https://ask3.ru/product2collationПартнерыhttps://comrades.ask3.ru


Совет. Чтобы искать на странице, нажмите Ctrl+F или ⌘-F (для MacOS) и введите запрос в поле поиска.
Arc.Ask3.ru: далее начало оригинального документа

Тип перекрестка — Википедия Jump to content

Тип пересечения

Из Википедии, бесплатной энциклопедии

В теории типов тип пересечения может быть присвоен значениям, которым можно присвоить как тип, так и тип пересечения. и тип . Этому значению может быть присвоен тип пересечения. в системе типа перекрестка . [1] Как правило, если диапазоны значений двух типов перекрываются, то значению, принадлежащему пересечению двух диапазонов, может быть присвоен тип пересечения этих двух типов. Такое значение можно безопасно передать в качестве аргумента функциям, ожидающим любой из двух типов. Например, в Java класс Boolean реализует как Serializable и Comparableинтерфейсы. Поэтому объект типа Boolean можно безопасно передавать функциям, ожидающим аргумент типа Serializable и функциям, ожидающим аргумент типа Comparable.

Типы пересечений — это составные типы данных . Подобно типам продуктов , они используются для присвоения объекту нескольких типов. Однако типы продуктов назначаются кортежам , поэтому каждому элементу кортежа назначается определенный компонент типа продукта. Для сравнения, базовые объекты типов пересечений не обязательно являются составными. Ограниченной формой типов пересечения являются уточняющие типы .

Типы пересечений полезны для описания перегруженных функций . [2] Например, если number => number это тип функции, принимающей число в качестве аргумента и возвращающей число, и string => string — это тип функции, принимающей строку в качестве аргумента и возвращающей строку, то пересечение этих двух типов можно использовать для описания (перегруженных) функций, которые выполняют одно или другое, в зависимости от типа входных данных, которые им предоставлены.

Современные языки программирования, включая Ceylon , Flow, Java , Scala , TypeScript и Whiley (см. сравнение языков с типами пересечений ), используют типы пересечений для объединения спецификаций интерфейса и выражения специального полиморфизма . В дополнение к параметрическому полиморфизму типы пересечений могут использоваться, чтобы избежать загрязнения иерархии классов из -за сквозных проблем и сократить шаблонный код , как показано в примере TypeScript ниже.

исследование Теоретико-типовое типов пересечений называется дисциплиной типов пересечений . [3] Примечательно, что завершение программы можно точно охарактеризовать с помощью типов пересечений. [4]

Пример TypeScript [ править ]

TypeScript поддерживает типы пересечений, [5] улучшение выразительности системы типов и уменьшение потенциального размера иерархии классов продемонстрировано следующим образом.

Следующий программный код определяет классы Chicken, Cow, и RandomNumberGenerator что у каждого есть метод produce возврат объекта любого типа Egg, Milk, или number. Кроме того, функции eatEgg и drinkMilk требуются аргументы типа Egg и Milk, соответственно.

class   Egg   {   частный   вид  :   "Egg"   } 
 class   Milk   {   частный   вид  :   "Milk"   } 

 // производит яйца 
 class   Chicken   {   Produce  ()   {   return   new   Egg  ();    }   } 

 // производит молоко 
 class   Cow   {   product  ()   {   return   new   Milk  ();    }   } 

 // создает случайное число 
 class   RandomNumberGenerator   {   product  ()   {   return   Math  .   случайный  ();    }   } 

 // требуется яйцо 
 function   eatEgg  (  egg  :   Egg  )   { 
     return   «Я съел яйцо».   ; 
  } 

 // требуется молоко 
 function   DrinkMilk  (  Milk  :   Milk  )   { 
     return   «Я выпил немного молока».   ; 
  } 

Следующий программный код определяет специальную полиморфную функцию animalToFood который вызывает функцию-член produce данного объекта animal. Функция animalToFood имеет аннотации двух типов, а именно ((_: Chicken) => Egg) и ((_: Cow) => Milk), подключенный через конструктор типа пересечения &. Конкретно, animalToFood при применении к аргументу типа Chicken возвращает объект типа type Eggи при применении к аргументу типа Cow возвращает объект типа type Milk. В идеале, animalToFood не должно быть применимо к любому объекту, имеющему (возможно, случайно) produce метод.

// дана курица, производит яйцо;   учитывая корову, производит молоко 
 let   AnimalToFood  :   ((  _  :   Курица  )   =>   Яйцо  )   &   ((  _  :   Корова  )   =>   Молоко  )   = 
     function   (  животное  :   любое  )   { 
         return   Animal  .   производить  (); 
      }; 

Наконец, следующий программный код демонстрирует безопасное использование приведенных выше определений.

вар   курица   =   новая   курица  (); 
  вар   корова   =   новая   корова  (); 
  вар   randomNumberGenerator   =   новый   RandomNumberGenerator  (); 

  консоль  .   журнал  (  курица  .  продукты  ());    // Яйцо { } 
 консоль  .   журнал  (  корова  .  продукция  ());    // Milk { } 
 консоль  .   журнал  (  randomNumberGenerator  .  Produce  ());    //0.2626353555444987 

 консоль  .   log  (  AnimalToFood  (  курица  ));    // Яйцо { } 
 консоль  .   журнал  (  животноеToFood  (  корова  ));    // Молоко { } 
 //console.log(animalToFood(randomNumberGenerator));   // ОШИБКА: аргумент типа «RandomNumberGenerator» не может быть назначен параметру типа «Cow» 

 console  .   log  (  eatEgg  (  AnimalToFood  (  курица  )));    // Я съел яйцо. 
  //console.log(eatEgg(animalToFood(cow)));   // ОШИБКА: Аргумент типа «Молоко» нельзя назначить параметру типа «Яйцо» 
 console  .   log  (  DrinkMilk  (  AnimalToFood  (  корова  )));    // Я выпил немного молока. 
  //console.log(drinkMilk(animalToFood(курица)));   // ОШИБКА: аргумент типа «Яйцо» нельзя назначить параметру типа «Молоко». 

Приведенный выше программный код имеет следующие свойства:

  • Строки 1–3 создают объекты. chicken, cow, и randomNumberGenerator соответствующего типа.
  • Строки 5–7 выводят для ранее созданных объектов соответствующие результаты (представленные в виде комментариев) при вызове. produce.
  • Строка 9 (соответственно 10) демонстрирует безопасное использование метода. animalToFood применительно к chicken (соответственно cow).
  • Если строка 11 не закомментирована, это приведет к ошибке типа во время компиляции. Хотя реализация animalToFood мог бы вызвать produce метод randomNumberGenerator, типа аннотация animalToFoodзапрещает это. Это соответствует предполагаемому смыслу animalToFood.
  • Строка 13 (соответственно 15) демонстрирует, что применение animalToFood к chicken (соответственно cow) приводит к объекту типа Egg (соответственно Milk).
  • Строка 14 (соответственно 16) демонстрирует, что применение animalToFood к cow (соответственно chicken) не приводит к созданию объекта типа Egg (соответственно Milk). Следовательно, если строка 14 (соответственно 16) не закомментирована, это приведет к ошибке типа во время компиляции.

Сравнение с наследованием [ править ]

Приведенный выше минималистский пример можно реализовать с помощью наследования , например, путем наследования классов Chicken и Cow из базового класса Animal. Однако в более крупных условиях это может оказаться невыгодным. Введение новых классов в иерархию классов не обязательно оправдано из-за сквозных проблем , а может быть и совершенно невозможно, например, при использовании внешней библиотеки. Можно представить, что приведенный выше пример можно расширить следующими классами:

  • класс Horse у которого нет produce метод;
  • класс Sheep у которого есть produce возврат метода Wool;
  • класс Pig у которого есть produce метод, который можно использовать только один раз, возвращая Meat.

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

Сравнение с утиным набором текста [ править ]

Приведенный выше минималистский пример уже показывает, что утиная типизация менее подходит для реализации данного сценария. В то время как класс RandomNumberGenerator содержит produce метод, объект randomNumberGenerator не должно быть веским аргументом в пользу animalToFood. Приведенный выше пример можно реализовать с помощью утиной печати, например, введя новое поле. argumentForAnimalToFood на занятия Chicken и Cow означающий, что объекты соответствующего типа являются действительными аргументами для animalToFood. Однако это не только увеличит размер соответствующих классов (особенно с введением большего количества методов, подобных animalToFood), но также является нелокальным подходом по отношению к animalToFood.

Сравнение с перегрузкой функций [ править ]

Приведенный выше пример можно реализовать с помощью перегрузки функции , например, реализовав два метода. animalToFood(animal: Chicken): Egg и animalToFood(animal: Cow): Milk. В TypeScript такое решение практически идентично приведенному примеру. Другие языки программирования, такие как Java , требуют отдельных реализаций перегруженного метода. Это может привести либо к дублированию кода , либо к шаблонному коду .

Сравнение с шаблоном посещений [ править ]

Приведенный выше пример можно реализовать с помощью шаблона посетителя . Для этого потребуется, чтобы каждый класс животных реализовал accept метод, принимающий объект, реализующий интерфейс AnimalVisitor(добавление нелокального шаблонного кода ). Функция animalToFood будет реализовано как visit способ реализации AnimalVisitor. К сожалению, связь между типом входа ( Chicken или Cow) и тип результата ( Egg или Milk) было бы трудно представить.

Ограничения [ править ]

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

Зависимый тип пересечения [ править ]

Зависимый тип пересечения , обозначаемый , является зависимым типом, в котором тип может зависеть от термина переменная . [6] В частности, если термин имеет зависимый тип пересечения , то термин имеет оба типа и тип , где это тип, который получается в результате замены всех вхождений термина переменная в по сроку .

Пример Scala [ править ]

Scala поддерживает объявления типов. [7] как члены объекта. Это позволяет типу члена объекта зависеть от значения другого члена, что называется типом, зависящим от пути . [8] Например, следующий текст программы определяет особенность Scala. Witness, который можно использовать для реализации шаблона Singleton . [9]

признак   Свидетель   { 
   тип   T 
   значение   :  {   T   } 
 } 

Вышеуказанная черта Witness заявляет член T, которому можно присвоить тип в качестве значения, а члену value, которому можно присвоить значение типа T. Следующий текст программы определяет объект booleanWitness как пример вышеуказанной черты Witness. Объект booleanWitness определяет тип T как Boolean и ценность value как true. Например, выполнение System.out.println(booleanWitness.value) принты true на консоли.

объект   booleanWitness   расширяет   Witness   { 
   тип   T   =   логическое 
   значение    =   true 
 } 

Позволять быть типом (в частности, типом записи ) объектов, имеющих член типа . В приведенном выше примере объект booleanWitness может быть назначен зависимый тип пересечения . Аргументация следующая. Объект booleanWitness имеет члена T которому присвоен тип Booleanкак его ценность. С Boolean это тип, объект booleanWitness имеет тип . Кроме того, объект booleanWitness имеет члена value которому присвоено значение true типа Boolean. Поскольку значение booleanWitness.T является Boolean, объект booleanWitness имеет тип . В целом объект booleanWitness имеет тип пересечения . Поэтому, представляя ссылку на себя как зависимость, объект booleanWitness имеет зависимый тип пересечения .

Альтернативно, приведенный выше минималистичный пример можно описать с помощью зависимых типов записей . [10] По сравнению с типами зависимых пересечений, типы зависимых записей представляют собой строго более специализированную концепцию теории типов. [6]

Пересечение типового семейства [ править ]

Пересечение семейства типов , обозначаемое , является зависимым типом, в котором тип может зависеть от термина переменная . В частности, если термин имеет тип , то для каждого члена типа , термин имеет тип . Это понятие еще называют неявным типом Пи , [11] отмечая, что аргумент не сохраняется на уровне срока.

Сравнение языков по типам пересечений [ править ]

Язык Активно развивается Парадигма(ы) Положение дел Функции
С# Да [12] Под обсуждением [13] Кроме того, параметры универсального типа могут иметь ограничения, которые требуют, чтобы их (мономорфизированные) аргументы типа реализовывали несколько интерфейсов, после чего тип времени выполнения, представленный параметром универсального типа, становится типом пересечения всех перечисленных интерфейсов.
Цейлон Нет [14] Поддерживается [15]
  • Тип уточнения
  • Состав интерфейса
  • Подтипирование по ширине
Ф# Да [16] Под обсуждением [17] ?
Поток Да [18] Поддерживается [19]
  • Тип уточнения
  • Состав интерфейса
Форсайт Нет Поддерживается [20]
  • Пересечение типов функций
  • Подтипы дистрибутивных, ко- и контравариантных функций
Джава Да [21] Поддерживается [22]
  • Тип уточнения
  • Состав интерфейса
  • Подтипирование по ширине
PHP Да [23] Поддерживается [24]
  • Тип уточнения
  • Состав интерфейса
Скала Да [25] Поддерживается [26] [27]
  • Тип уточнения
  • Состав черт
  • Подтипирование по ширине
Машинопись Да [28] Поддерживается [5]
  • Пересечение произвольного типа
  • Состав интерфейса
  • Подтипирование по ширине и глубине
Пока Да [29] Поддерживается [30] ?

Ссылки [ править ]

  1. ^ Барендрегт, Хенк; Коппо, Марио; Дезани-Чианкаглини, Марианджола (1983). «Фильтр лямбда-модели и полнота присвоения типа». Журнал символической логики . 48 (4): 931–940. дои : 10.2307/2273659 . JSTOR   2273659 . S2CID   45660117 .
  2. ^ Палсберг, Йенс (2012). «Перегрузка NP-завершена». Логика и семантика программ . Конспекты лекций по информатике. Том. 7230. стр. 204–218. дои : 10.1007/978-3-642-29485-3_13 . ISBN  978-3-642-29484-6 .
  3. ^ Хенк Барендрегт; Уил Деккерс; Ричард Стэтман (20 июня 2013 г.). Лямбда-исчисление с типами . Издательство Кембриджского университета. стр. 1–. ISBN  978-0-521-76614-2 .
  4. ^ Гилезан, Сильвия (1996). «Сильная нормализация и типизация с типами пересечений» . Журнал формальной логики Нотр-Дама . 37 (1): 44–52. дои : 10.1305/ndjfl/1040067315 .
  5. ^ Перейти обратно: а б «Типы пересечений в TypeScript» . Проверено 1 августа 2019 г.
  6. ^ Перейти обратно: а б Копылов, Алексей (2003). «Зависимое пересечение: новый способ определения записей в теории типов». 18-й симпозиум IEEE по логике в информатике . LICS 2003. Компьютерное общество IEEE. стр. 86–95. CiteSeerX   10.1.1.89.4223 . дои : 10.1109/LICS.2003.1210048 .
  7. ^ «Объявления типов в Scala» . Проверено 15 августа 2019 г.
  8. ^ Амин, Нада; Грюттер, Сэмюэл; Одерский, Мартин; Ромпф, Тиарк; Стуки, Сандро (2016). «Сущность зависимых типов объектов». Список успехов, которые могут изменить мир (PDF) . Конспекты лекций по информатике. Том. 9600. Спрингер. стр. 249–272. дои : 10.1007/978-3-319-30936-1_14 . ISBN  978-3-319-30935-4 .
  9. ^ «Синглетоны в бесформенной библиотеке Scala» . Гитхаб . Проверено 15 августа 2019 г.
  10. ^ Поллак, Роберт (2000). «Зависимо типизированные записи для представления математической структуры». Доказательство теорем в логике высшего порядка, 13-я Международная конференция . TPHOLs 2000. Спрингер. стр. 462–479. дои : 10.1007/3-540-44659-1_29 .
  11. ^ Стамп, Аарон (2018). «От реализуемости к индукции через зависимое пересечение» . Анналы чистой и прикладной логики . 169 (7): 637–655. дои : 10.1016/j.apal.2018.03.002 .
  12. ^ «Руководство по C#» . Проверено 8 августа 2019 г.
  13. ^ «Обсуждение: типы объединения и пересечения в C Sharp» . Гитхаб . Проверено 8 августа 2019 г.
  14. ^ «Затмение Цейлон™» . 19 июля 2017 года . Проверено 16 августа 2023 г.
  15. ^ «Типы перекрестков на Цейлоне» . 19 июля 2017 года . Проверено 8 августа 2019 г.
  16. ^ «Фонд программного обеспечения F#» . Проверено 8 августа 2019 г.
  17. ^ «Добавить типы пересечений к F Sharp» . Гитхаб . Проверено 8 августа 2019 г.
  18. ^ «Flow: средство проверки статического типа для JavaScript» . Проверено 8 августа 2019 г.
  19. ^ «Синтаксис типа пересечения в потоке» . Проверено 8 августа 2019 г.
  20. ^ Рейнольдс, JC (1988). Предварительный проект языка программирования Форсайт.
  21. ^ «Программное обеспечение Java» . Проверено 8 августа 2019 г.
  22. ^ «Тип пересечения (Java SE 12 и JDK 12)» . Проверено 1 августа 2019 г.
  23. ^ «php.net» .
  24. ^ «PHP.Watch — PHP 8.1: Типы пересечений» .
  25. ^ «Язык программирования Scala» . Проверено 8 августа 2019 г.
  26. ^ «Составные типы в Scala» . Проверено 1 августа 2019 г.
  27. ^ «Типы пересечений в Дотти» . Проверено 1 августа 2019 г.
  28. ^ «TypeScript — масштабируемый JavaScript» . Проверено 1 августа 2019 г.
  29. ^ «Whiley: язык программирования с открытым исходным кодом и расширенной статической проверкой» . Проверено 1 августа 2019 г.
  30. ^ «Спецификация языка Whaley» (PDF) . Проверено 1 августа 2019 г.
Arc.Ask3.Ru: конец оригинального документа.
Arc.Ask3.Ru
Номер скриншота №: 479815E005A20BBC64C923A50BE596C7__1700472420
URL1:https://en.wikipedia.org/wiki/Intersection_type
Заголовок, (Title) документа по адресу, URL1:
Intersection type - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть, любые претензии не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, денежную единицу можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)