私が達成したいのは、適切な実装を行うことです
def dynamix[A, B](a: A): A with B
B が何であるかは知っているかもしれませんが、A が何であるかはわかりません (ただし、B に自己型がある場合は、A にいくつかの制約を追加できます)。scala コンパイラは上記の署名に満足していますが、実装がどのようになるかはまだわかりませんでした。
私の頭に浮かんだいくつかのオプション:
- リフレクション/動的プロキシの使用。
- 最も単純なケース: A は Java レベルのインターフェースであり、B をインスタンス化でき、自己型はありません。難しいことではないと思います (予想外の厄介な問題に遭遇しない限り):
新しい B (b) を作成し、A と B の両方を実装し、a または b のいずれかに委譲する呼び出しハンドラーを使用するプロキシも作成します。 - B をインスタンス化できない場合でも、そのサブクラスを作成して、上記で説明したようにすることができます。自己型もある場合は、おそらくあちこちで委任が必要になるでしょうが、それでも機能する可能性があります。
- しかし、A が具象型で、適切なインターフェイスが見つからない場合はどうなるでしょうか。
- さらに問題が発生する可能性はありますか (たとえば、線形化に関連するものや、Java の相互運用性を支援する特別な構成要素など)?
- 最も単純なケース: A は Java レベルのインターフェースであり、B をインスタンス化でき、自己型はありません。難しいことではないと思います (予想外の厄介な問題に遭遇しない限り):
- mixin の代わりに一種のラッピングを使用して B[A] を返すと、b から a にアクセスできます。
残念なことに、この場合、呼び出し元はネスティングがどのように行われるかを知る必要があります。必要な機能にアクセスするための適切なレベルのネストであるため、解決策とは考えていません。 - コンパイラ プラグインの実装。私はそれを経験したことはありませんが、私の直感は、それは簡単ではないということです. Kevin Wright のautoproxyプラグインにも少し似たような目的があると思いますが、私の問題には十分ではありません (まだ?)。
他に有効なアイデアはありますか?どの方法をお勧めしますか? どのような「挑戦」が待っているのでしょうか。
それとも、現在の Scala 制約では不可能なため、忘れるべきでしょうか?
問題の背後にある意図: ビジネス ワークフローがあるとしますが、厳密すぎません。順序が固定されているステップもあれば、固定されていないステップもありますが、最後にすべてのステップを実行する必要があります (または、さらに処理が必要なステップもあります)。
もう少し具体的な例: A があり、それに B と C を追加できます。どちらが先かは気にしませんが、最後には A と B と C が必要になります。
コメント: 私は Groovy についてあまり知りませんが、SO がこの質問をポップアップしました。