2

この問題に遭遇したとき、私はより高い種類と型の境界で少し遊んでみました。私の使用例は、GenericAction インスタンスを Request の任意のサブタイプ、または Request タイプ自体でパラメーター化できるようにすることです。Action トレイトは、GenericAction トレイトをデフォルト タイプの Request で拡張します (この場合、Request の匿名インスタンスのみが生成されます)。

trait Request[+A]

trait GenericAction[A, R[_] <: Request[_]]

trait Action[A] extends GenericAction[A, Request]

trait ActionBuilderBase[R[_] <: Request[_], G[_] <: GenericAction[_,R]]

ActionBuilderBase には、サブトレイトの ActionBuilder および ActionBuilder2 と共有されるユーティリティ メソッドがあります。ActionBuilder は、デフォルトの Action[A] および Request[A] インスタンスを生成します。

trait ActionBuilder extends ActionBuilderBase[Request,Action]

ここまでは順調ですが、R と GenericAction のサブタイプで ActionBuilderBase を拡張する別のトレイトを作成しようとすると (この場合、GenericAction の匿名インスタンスが作成されます)、コンパイルに失敗します。その理由は、最初の ActionBuilder の場合、以下の例とは異なり、リクエスト タイプが既に「入力」されているためだと思います (Action[A] には既にリクエスト タイプ == Request があるため)。この例を機能させるには、何を「記入」する必要がありますか?

//Fails with "GenericAction takes two type parameters, expected: one" - what should the type annotation for GenericAction look like?
trait ActionBuilder2[R[_] <: Request[_]] extends ActionBuilderBase[R,GenericAction]
4

1 に答える 1

7

このような場合、次のように書けると便利です。

trait ActionBuilder2[R[_] <: Request[_]] extends
  ActionBuilderBase[R, GenericAction[_, R]]

部分的に適用することを示しますGenericAction。残念ながら、これは有効な Scala 構文ではありません (ただし、Erik Osheim には、非常によく似たものを作成できるコンパイラ プラグインがあります)。

ただし、「タイプラムダトリック」を使用できます。

trait ActionBuilder2[R[_] <: Request[_]] extends
  ActionBuilderBase[R, ({ type L[A] = GenericAction[A, R] })#L]

それがどのように機能するかの詳細な説明については、この回答を参照してください。

于 2012-10-21T17:50:59.957 に答える