Z ciekawości, czy istnieją języki, które pozwalają ci ustawiać arytmetykę typów, aby tworzyć nowe typy? Coś jak:
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()
Wiem, że w niektórych językach można wyrażać te idee (tj. Java ma List<Comparable & Serializable>
na celu połączenie interfejsów), ale nigdy nie słyszałem o języku, który obsługuje arytmetykę typów. Dzięki!
programming-languages
type-systems
Haldean Brown
źródło
źródło
CanWriteAndCompare extends Serializable, Comparable {}
) I zastanawiałem się, jak to uogólnić.A
a lub aB
, z dwiema implementacjami, które wyglądają dokładnie tak samo. W metodzie nazywam metodę polimorficzną, która może przyjąć wartośćA
a lub aB
, więc implementacje są takie same, ale ponieważ muszę wziąć dwa różne typy, potrzebuję dwóch implementacji. Byłoby łatwiej, gdybym mógłmyMethod(A | B aOrB)
.Or
operacja może być emulowana przez wielokrotne dziedziczenie.Odpowiedzi:
Tangent ( specyfikacja 0.3 ) używa czegoś podobnego do tego. (zrzeczenie się: to mój mały projekt badawczy)
Obecnie
with
działa jako operator modelowania dziedziczenia przez związki, chociaż pragmatyzm sprawił, że nie jest on przemienny. Po wprowadzeniu implementacji metod ścisłe połączenie metod o tej samej nazwie często nie jest tym, czego chcesz, i i tak nie można tego zrobić właściwie.intersect
obsługiwane jest wnioskowanie o typach modeli dla czegoś takiego,foo(T,T)
gdzie parametry są różne.Uzupełnienia były interesujące, ale doprowadziły do częściowych typów, które wydawały się nie tak przydatne i / lub kłopotliwe do prawidłowego włączenia - więc nie zostały uwzględnione.
Wiem, że natknąłem się na kilka innych języków badawczych, które miały coś podobnego, ale w tej chwili ich nie pamiętam. Głównym problemem jest to, że rzeczy nie są tak naprawdę przydatne bez strukturalnego pisania, co samo w sobie nie jest zbyt popularne. Drugim jest to, że potrzebujesz jakiegoś rodzaju (rodzaju typów) do przechowywania skonstruowanego typu, w przeciwnym razie jest to po prostu skrót dla czegoś, co nie jest szczególnie idiomatyczne bez tej możliwości. A to znacznie mniej powszechne niż nawet pisanie strukturalne.
Jest tendencyjny i niewiele, ale jest.
źródło
Tak, Cejlon jest językiem z typami połączeń i skrzyżowań ad hoc, jak opisano w tym rozdziale z wycieczki po Cejlonie:
To niesamowita liczba fajnych idiomów, które z tego czerpiesz. Oto jeden interesujący przykład, który niedawno napisałem na blogu . A oto krótka prezentacja, w której szybko przeglądam kilka prostych idiomów .
Co więcej, typy unii / przecięcia są „brakującym ogniwem”, które sprawia, że wnioskowanie argumentów typu ogólnego naprawdę działa poprawnie na Cejlonie, w przeciwieństwie do innych języków, które łączą podtyp i polimorfizm parametryczny.
Zauważ, że istnieją ograniczenia tego rodzaju „arytmetyki typu”, jak to opisałeś. Na przykład nie można mieć ustawionego operatora dopełniania na poziomie typu, przynajmniej nie bez wprowadzenia nierozstrzygalności.
HTH
źródło
Scala obsługuje go częściowo (przecięcia, ale nie związki), a każdy język z podtypami strukturalnymi (myślę, że OCaml jest przykładem) lub system typów wystarczająco mocny, aby go naśladować (Haskell jest klasycznym), będzie miał pełne „typy-jako-zestawy "możliwości, przynajmniej w obrębie fragmentu systemu typów, który akceptuje takie rzeczy (istotne, gdy jest emulowany ala HList / OOHaskell).
Ponieważ nie znam zbyt dobrze OCaml, podam część twojego przykładu, która działa w Scali:
Wersja dla Haskell zależałaby od używanego systemu nagrań i prawdopodobnie byłaby nieco niezręczna, ponieważ byłaby emulowana, a nie natywnie obsługiwana.
O ile mi wiadomo, Ceylon ma wbudowane w język zarówno typy przecinania się, jak i unii, więc można przypuszczać, że można je zakodować na poziomie typu „xor”.
źródło
Java obsługuje skrzyżowania typów interfejsów w niektórych kontekstach, choć nie jest to tak dalece, jak mogę stwierdzić, pozwalając na tworzenie zmiennych typów skrzyżowań. Rodzaje skrzyżowań mogą wchodzić w grę, na przykład podczas korzystania z
? :
operatora. Jeśli drugi i trzeci operand tego operatora są niepowiązanymi interfejsami, które dziedziczą po nakładających się zestawach interfejsów, wynikiem operatora będzie zestaw interfejsów, które są wspólne dla obu.źródło
Common Lisp pozwala definiują nowy typ użyciu
not
,and
orazor
operatorzy (patrz typu specyfikatory łączących ).źródło