Чи існують мови програмування, які дозволяють встановлювати арифметику на типи?


9

Чи не цікаво, чи існують мови, які дозволяють встановлювати арифметику на типи для створення нових типів? Щось на зразок:

interface A {
  void a();
  void b();
}

interface B {
  void b();
  void c();
}

interface C = A & B; // has b()
interface D = A | B; // has a(), b() and c()
interface E = (A & B) ^ B; // has c()

Я знаю, що в деяких мовах ці ідеї можна висловити (тобто, Java має List<Comparable & Serializable>об'єднання інтерфейсів), але я ніколи не чув про мову, яка підтримує арифметику типу. Дякую!


7
Чим корисний такий механізм?
Роберт Харві

4
Шаблон, який я багато бачив, - це інтерфейс, який розширює два інших інтерфейси і нічого не додає (тобто CanWriteAndCompare extends Serializable, Comparable {}), і я думав, як це узагальнити.
Haldean Brown

2
Також я зіткнувся із випадком, коли у мене є метод, який може приймати Aабо a B, з двома реалізаціями, які виглядають абсолютно однаково. У методі я викликаю поліморфний метод, який може приймати Aабо a B, тому реалізація однакова, але оскільки мені потрібно взяти два різних типи, мені потрібно дві реалізації. Це було б простіше, якби я міг це зробити myMethod(A | B aOrB).
Haldean Brown


1
Orоперація може бути емульована багаторазовим успадкуванням.
користувач

Відповіді:


4

Tangent ( 0,3 специфікації ) використовує для цього щось подібне. (відмова від відповідальності: це мій власний маленький дослідницький проект)

В даний withчас оператор профспілки моделює спадщину, хоча прагматизм зробив це не комутативним. Після того, як ви впроваджуєте реалізацію методів, суворий об'єднання методів з тим самим іменем часто не є тим, що ви хочете, і неможливо зробити правильно в будь-якому випадку.

intersectпідтримується те, що моделі вводять умовивід для чогось такого, foo(T,T)де параметри різні.

Доповнення були цікавими, але призводили до часткових типів, які здавалися не такими корисними та / або клопітними, щоб правильно їх включити - тому вони не включаються.

Я знаю, що є кілька інших мов дослідження, на які я зіткнувся, які мали щось подібне, але наразі не можу їх запам'ятати. Основне питання полягає в тому, що речі не дуже корисні без структурного набору тексту, що не дуже страшно популярне. Інша полягає в тому, що для зберігання сконструйованого типу вам потрібен якийсь тип (тип), інакше це просто скорочення для чогось, що не має особливих ідіотичних без цієї можливості. І це набагато рідше, ніж навіть структурний набір тексту.

Це упереджено, і це не так багато, але є.


5

Так, Цейлон - це мова з спеціальними типами з’єднання та перетину, як описано в цій главі з Цейлонської екскурсії:

http://ceylon-lang.org/documentation/1.0/tour/types/

Дивовижна кількість крутих ідіом, які ви отримуєте з цього. Ось один цікавий приклад, про який я нещодавно блогував . Ось коротка презентація, в якій я швидко змалюю кілька простих ідіом .

Ще краще, типи об'єднання / перетину - це "відсутня ланка", завдяки якій загальний аргумент типу дійсно працює правильно на Цейлоні на відміну від інших мов, які поєднують підтип і параметричний поліморфізм.

Зауважте, що для цього виду "арифметики типу" є обмеження, як ви описали. Наприклад, ви не можете мати оператора доповнення набору на рівні типу, принаймні не без введення невідмінюваності.

HTH


3

Scala підтримує його частково (перетини, але не спілки), і будь-яка мова зі структурним підтипом (я думаю, OCaml є прикладом) або типовою системою, достатньо потужною для емуляції, що (Haskell є класичним) матиме повні "типи-набори" "можливостей, щонайменше, у фрагменті системи типу, яка приймає такі речі (актуально, коли вона емульована ala HList / OOHaskell).

Оскільки я не дуже добре знаю OCaml, я наведу частину вашого прикладу, що працює у Scala:

trait A {
  def a(): Unit
  def b(): Unit
}

abstract class B { // just to prove it works with both traits and classes
  def b(): Unit
  def c(): Unit
}

type C = A with B
type D = { def b(): Unit } // not an exact translation, because unions aren't directly available
// type `E` is unrepresentable

Версія для Haskell залежатиме від системи записів, яку ви використовували, і, ймовірно, буде дещо незграбною, тому що вона буде імітуватися, а не підтримуватися на самому світі.

Наскільки я знаю, на Цейлоні є в мові вбудовані як перетинання, так і з'єднання типів на повну потужність, тож можна вважати кодування типу "xor" на рівні цих типів.


1

Java підтримує перетинання типів інтерфейсів у деяких контекстах, хоча це не настільки, наскільки я можу сказати, дозволяють створювати змінні типів перетину. Типи перетину можуть вступати в гру, наприклад, при використанні ? :оператора. Якщо другий і третій операнди цього оператора є неспорідненими інтерфейсами, які успадковуються від перекриваються наборів інтерфейсів, результатом оператора буде набір спільних для обох інтерфейсів.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.