Jump to content

Система структурных типов

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

Описание [ править ]

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

Например, OCaml использует структурную типизацию в методах для совместимости типов объектов. Go использует структурную типизацию методов для определения совместимости типа с интерфейсом. Функции шаблонов C++ демонстрируют структурную типизацию аргументов типа. Haxe использует структурную типизацию, но классы не имеют структурных подтипов.

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

Существует различие между структурной заменой предполагаемого и непредполагаемого полиморфизма. Некоторые языки, такие как Haskell , не заменяют структурно в случае, когда ожидаемый тип объявлен (т. е. не выводится), например, заменяют только функции, которые являются полиморфными на основе сигнатур посредством вывода типа. [1] Тогда невозможно случайно создать подтип невыведенного типа, хотя все же можно обеспечить явное преобразование в невыведенный тип, который вызывается неявно.

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

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

В 1990 году Кук и др. доказали, что наследование не является подтипированием в структурно-типизированных объектно-ориентированных языках. [2]

Проверка совместимости двух типов на основе структурной типизации является нетривиальной операцией, например, требует сохранения стека ранее проверенных типов. [3]

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

Объекты в OCaml структурно типизированы по именам и типам их методов.

Объекты можно создавать напрямую ( непосредственные объекты ), минуя именительный класс. Классы служат только функциями для создания объектов.

 # let x =
     object
       val mutable x = 5
       method get_x = x
       method set_x y = x <- y
     end;;
 val x : < get_x : int; set_x : int -> unit > = <obj>

Здесь интерактивная среда выполнения OCaml для удобства распечатывает предполагаемый тип объекта. Его тип ( < get_x : int; set_x : int -> unit >) определяется только своими методами. Другими словами, тип x определяется типами методов «get_x: int» и «set_x: int -> unit», а не каким-либо именем. [4]

Чтобы определить другой объект, который имеет те же методы и типы методов:

 # let y =
     object
       method get_x = 2
       method set_x y = Printf.printf "%d\n" y
     end;;
 val y : < get_x : int; set_x : int -> unit > = <obj>

OCaml считает их однотипными. Например, оператор равенства принимает только два значения одного типа:

 # x = y;;
 - : bool = false

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

Можно определить функцию, которая вызывает метод:

 # let set_to_10 a = a#set_x 10;;
 val set_to_10 : < set_x : int -> 'a; .. > -> 'a = <fun>

Выведенный тип для первого аргумента ( < set_x : int -> 'a; .. >) интересно. .. означает, что первым аргументом может быть любой объект, имеющий метод «set_x», который принимает в качестве аргумента целое число.

Поэтому его можно использовать на объекте x:

 # set_to_10 x;;
 - : unit = ()

Можно создать другой объект, который будет иметь этот метод и тип метода; остальные методы не имеют значения:

 # let z =
     object
       method blahblah = 2.5
       method set_x y = Printf.printf "%d\n" y
     end;;
 val z : < blahblah : float; set_x : int -> unit > = <obj>

На нем также работает функция set_to_10:

 # set_to_10 z;;
 10
 - : unit = ()

Это показывает, что совместимость таких вещей, как вызов метода, определяется структурой.

Давайте определим синоним типа для объектов, имеющих только метод get_x и никаких других методов:

 # type simpler_obj = < get_x : int >;;
 type simpler_obj = < get_x : int >

Объект x не относится к этому типу; но структурно, x принадлежит к подтипу этого типа, поскольку x содержит расширенный набор своих методов. Так x можно привести к этому типу:

 # (x :> simpler_obj);;
 - : simpler_obj = <obj>
 # (x :> simpler_obj)#get_x;;
 - : int = 10

Но не возражать z, поскольку это не структурный подтип:

# (z :> simpler_obj);;
This expression cannot be coerced to type simpler_obj = < get_x : int >;
it has type < blahblah : float; set_x : int -> unit > but is here used with type
  < get_x : int; .. >
The first object type has no method get_x

Это показывает, что совместимость расширяющихся принуждений носит структурный характер.

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

  1. ^ «Полиморфизм на основе сигнатур» .
  2. ^ Кук, WR; Хилл, WL; Каннинг, PS (январь 1990 г.). «Наследование — это не подтип». Материалы 17-го симпозиума ACM SIGPLAN-SIGACT по принципам языков программирования - POPL '90 . Сан-Франциско, Калифорния. стр. 125–135. дои : 10.1145/96709.96721 . ISBN  978-0897913430 . S2CID   8225906 . {{cite book}}: CS1 maint: отсутствует местоположение издателя ( ссылка )
  3. ^ «Совместимость типов: имя против структурной эквивалентности» .
  4. ^ «Типы объектов» .

Внешние ссылки [ править ]

Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 72c2f21775092d7d35815f6b7972bf27__1705506540
URL1:https://arc.ask3.ru/arc/aa/72/27/72c2f21775092d7d35815f6b7972bf27.html
Заголовок, (Title) документа по адресу, URL1:
Structural type system - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)