2017-01-17 3 views
1

私は、traitの実装でかなり単純な状況だと思っていますが、私は欠けている単純な解決策がいくつかあると思います。私はそれが呼び出されることに価値具体的な実装の唯一のタイプとしてのパラメータ(およびリターンとして受け入れ特性上のメソッドを持っているしたいと思います。具体的:。Scala traitメソッドは型の実装に限定されています

trait Foo { 
    type ConcreteFoo // what to put here? 
    def combine(that:ConcreteFoo):ConcreteFoo 
} 

class FooImpl1 extends Foo { 
    def combine(that:FooImpl1):FooImpl1 = { 
    // implementation 
    } 
} 

class FooImpl2 extends Foo { 
    def combine(that:FooImpl2):FooImpl2 = { 
    // implementation 
    } 
} 

今私が持っています実装するクラスのtype Self = FooImpl、私はむしろ、可能な場合、それの世話をする特質上の何かを持っていると思います

+0

このソリューションは、f-bounded polymorphismと呼ばれます。ここをクリックしてください:https://twitter.github.io/scala_school/advanced-types.html#fbounded – maasg

答えて

1

これは正確ですF-Bounded Polymorphism:

trait Foo[T <: Foo[T]] 
    def combine(that: T): T 
} 

class FooImpl1 extends Foo[FooImpl1] { 
    def combine(that: FooImpl1): FooImpl1 = { 
    ??? 
    } 
} 

class FooImpl2 extends Foo[FooImpl2] { 
    def combine(that: FooImpl2): FooImpl2 = { 
    ??? 
    } 
} 
+0

パーフェクト!なぜ私はこのアプローチを最初にやっていないのか覚えています。 'Foo'は実際に型パラメータも取るので、私が具体的な' Foo'実装に制限されたくないときは、どのようにして型パラメータを広げずにそれを行うのかわかりません。すなわち、 '形質Foo [A、F <:Foo [A、F]]; def accumulate(f:Foo [A、_]) 'は失敗します。なぜなら、' _'は境界を満たさないためですが、それをどのように埋めるのか分かりません。 –

+0

@John 'def accumulate(f:F)'は、すでに特性宣言によって束縛されているので、行うことができます。 –

+0

申し訳ありませんが、私はそのスニペットではっきりしていませんでした。 'accumulate'は' Foo'では定義されていませんが、汎用 'Foo'では定義されていません。だから、実際に 'def蓄積[A](f:Foo [A、_])'のようなものを想像してください。私はdef def [A、F <:Foo [A、F]](f:F)を積み上げることができることを知っていますが、それはまさに '避けたいタイプのパラメータの拡散'この場合、消去された型パラメータに適切な境界を指定する理由はありますか?明らかに、素朴なアプローチは、無限の回帰を与えます: 'def accumulate [A](f:Foo [A、_ <:Foo [A、_ <:Foo [A、_ ...]))' –

0

あなたはこのようなあなたの形質に型パラメータを追加することができます。

trait Foo[A] { 
    def combine(that: A): A 
} 

class FooImpl1 extends Foo[FooImpl1] { 
    override def combine(that: FooImpl1): FooImpl1 = ??? 
} 

class FooImpl2 extends Foo[FooImpl2] { 
    override def combine(that: FooImpl2): FooImpl2 = ??? 
} 
関連する問題