型に算術を設定できるプログラミング言語はありますか?


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
そのようなメカニズムはどのように役立ちますか?
Robert Harvey、

4
私がよく見たパターンは、他の2つのインターフェースを拡張し、何も追加しないインターフェース(つまり、CanWriteAndCompare extends Serializable, Comparable {})であり、これを一般化する方法を考えていました。
Haldean Brown、2012

2
また、2つの実装がまったく同じに見える、Aまたはをとることができるメソッドがあるケースに今日遭遇しましたB。メソッドでは、Aまたはを受け取ることができるポリモーフィックメソッドを呼び出しているBため、実装は同じですが、2つの異なる型をとる必要があるため、2つの実装が必要です。できればもっと簡単でしょうmyMethod(A | B aOrB)
Haldean Brown、2012

1
ここを参照してください:msdn.microsoft.com/en-us/library/4taxa8t2.aspx
Robert Harvey

1
Or操作は多重継承によってエミュレートできます。
ユーザー

回答:


4

Tangent0.3 spec)はこれに似たものを使用しています。(免責事項:これは私自身の小さな研究プロジェクトです)

現在with、継承をモデル化する共用体演算子として機能しますが、実用主義により可換性はなくなりました。メソッドに実装を導入すると、同じ名前のメソッドの完全な結合は、多くの場合、希望どおりではなく、とにかく正しく実行することが不可能になります。

intersectfoo(T,T)パラメータが異なる場所などの型推論をモデル化することがサポートされています。

補集合は興味深いものでしたが、正しく含めるのにあまり役に立たない、または面倒であると思われる部分型につながりました。そのため、含まれていません。

私が遭遇した他のいくつかの研究言語が類似したものを持っていることは知っていますが、現時点では覚えていません。主な問題は、構造化タイピングなしでは物事は実際には役に立たないことであり、それ自体はそれほど人気が​​ありません。もう1つは、構築されたタイプを格納するために何らかの種類(タイプのタイプ)が必要か、それともその機能がなければ特に慣用的ではないものの省略形にすぎないということです。そして、それは構造型タイピングよりもはるかに一般的ではありません。

それは偏っており、多くはありませんが、それはあります。


5

はい、セイロンは、アドホックなユニオンおよびインターセクションタイプを備えた言語です。セイロンツアーのこの章で説明されています。

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

あなたがこれから得るクールなイディオムの数は驚くべきことです。ここに私が最近ブログに書いた興味深い例があります。そして、ここにいくつかの簡単なイディオムをすばやく説明する短いプレゼンテーションがあります。

さらに良いことに、共用体/交差型は、サブタイプとパラメトリック多態性を組み合わせる他の言語とは対照的に、一般的な型引数の推論をCeylonで正しく機能させる「ミッシングリンク」です。

あなたがそれを説明したように、この種の「タイプ算術」には制限があることに注意してください。たとえば、型レベルで集合補数演算子を使用することはできません。

HTH


3

Scalaはそれを部分的にサポートします(交差ではなくユニオンではありません)、構造サブタイプ(OCamlは一例だと思います)、またはそれをエミュレートするのに十分強力な型システム(Has​​kellは古典的なもの)は完全な「型としてのセット」を持ちます"機能、少なくともそのようなものを受け入れる型システムのフラグメント内(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のバージョンは、使用しているレコードシステムに依存し、ネイティブでサポートされているのではなくエミュレートされるため、多少扱いにくいかもしれません。

私の知る限り、Ceylonには共通型 union型の両方がフル機能で言語に組み込まれているため、型レベルの「xor」をそれらの観点からエンコードすることができます。


1

Javaは、一部のコンテキストでインターフェイスタイプの交差をサポートしていますが、交差タイプの変数の作成を許可することはできません。交差点タイプは、たとえば、? :オペレーターを使用するときに役立ちます。その演算子の2番目と3番目のオペランドが、インターフェースの重複セットから継承する無関係のインターフェースである場合、オペレーターの結果は、両方に共通のインターフェースのセットになります。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.