1. ホーム
  2. language-agnostic

[解決済み】実存型とは何ですか?

2022-04-19 17:07:29

質問

ウィキペディアの記事を読みました。 実存的なタイプ . 実存演算子(∃)があるから実存型と呼ばれるのだと、私は解釈しました。でも、何が言いたいのかよくわからない。とは何が違うのでしょうか?

T = ∃X { X a; int f(X); }

そして

T = ∀x { X a; int f(X); }

?

解決方法は?

ユニバーサルタイプを定義した場合 ∀X と言っているようなものです。 私はその型について何も知らなくても仕事はできます。 X .

誰かが実存的な型を定義するとき ∃X と言っているようなものです。 ここでは好きな型を使いますが、あなたはその型について何も知らないので、この型は X .

ユニバーサルタイプでは、次のような書き方ができます。

void copy<T>(List<T> source, List<T> dest) {
   ...
}

copy 関数は T は実際にどうなるのか、知る必要はありません。

存在型なら、こんなことも書けるようになる。

interface VirtualMachine<B> {
   B compile(String source);
   void run(B bytecode);
}

// Now, if you had a list of VMs you wanted to run on the same input:
void runAllCompilers(List<∃B:VirtualMachine<B>> vms, String source) {
   for (∃B:VirtualMachine<B> vm : vms) {
      B bytecode = vm.compile(source);
      vm.run(bytecode);
   }
}

リスト内の各仮想マシン実装は、異なるバイトコードタイプを持つことができます。 そのため runAllCompilers 関数は、バイトコードが何であるかを知らないが、知る必要はない。 VirtualMachine.compile から VirtualMachine.run .

Java型のワイルドカード(例. List<?> は、実存的な型の非常に限定された形式です。

更新してください。 言い忘れていましたが、普遍型を使って実存型をシミュレートすることができます。 まず、普遍型をラップして、型パラメータを隠します。 次に、制御を反転させます(これは、上記の定義における "you" と "I" の部分を効果的に交換するもので、実存型と普遍型との主な違いです)。

// A wrapper that hides the type parameter 'B'
interface VMWrapper {
   void unwrap(VMHandler handler);
}

// A callback (control inversion)
interface VMHandler {
   <B> void handle(VirtualMachine<B> vm);
}

これで VMWrapper は、私たち自身の VMHandler これは、普遍的な型である handle という関数があります。 正味の効果は同じで、私たちのコードは B を不透明とする。

void runWithAll(List<VMWrapper> vms, final String input)
{
   for (VMWrapper vm : vms) {
      vm.unwrap(new VMHandler() {
         public <B> void handle(VirtualMachine<B> vm) {
            B bytecode = vm.compile(input);
            vm.run(bytecode);
         }
      });
   }
}

VMの実装例です。

class MyVM implements VirtualMachine<byte[]>, VMWrapper {
   public byte[] compile(String input) {
      return null; // TODO: somehow compile the input
   }
   public void run(byte[] bytecode) {
      // TODO: Somehow evaluate 'bytecode'
   }
   public void unwrap(VMHandler handler) {
      handler.handle(this);
   }
}