2016-04-12 9 views
1

が必要ですScalaのタイピング私は、例えば、</p> <pre><code>abstract class ResultProvider[+T: Writes](db: DB) { def get(id: Long): Future[Seq[T]] } </code></pre> <p>そして、いくつかの実装親の一般的なクラスを持っている</p> <p>次構築しようとしている暗黙の

class LengthProvider(db: DB) extends ResultProvider[LengthResult](db){ 
    override def get (userId: Long): Future[Seq[LengthResult]] = ... 
} 

object LengthProvider extends ((DB) => DisciplinePredictor) { 
    override def apply(db: DB) = new LengthProvider(db) 
} 

私は、構成マップを次ています

val providers: Map[String, ((DB) => ResultProvider[???])] = Map(
    "length" -> LengthProvider, 
    "width" -> WidthProvider, 
    ... 
) 

私の質問は、私は???の場所に置くべきものです。理想的には、それはに行くので、このタイプは暗黙的に実装されたWritesがあることだけを気にして、T : Writesのようなものにするのが理想です。 Anyでコンパイルされますが、暗黙的に実装する必要がある情報は失われます。 または別の方法を使用する必要がありますか?おそらくすべての結果のケースクラス(たとえばLengthResult)のスーパークラスを作成できますが、私はそのimplicitsを取り除きたいと思います。

+0

try 'T <:Writes' –

+0

@AlexanderArendarそれはまったく欲しいものではありません。 –

答えて

1

あなたは(あなたがこの構文に慣れていない場合は、「実存の種類」で検索)ResultProvider[_]を書くことができるはずですが、あなたは暗黙的に名前を付ける必要があります:

他の場所
abstract class ResultProvider[+T](db: DB)(implicit val writes: Writes[T]) { ... } 

val provider: ResultProvider[_] = providers("length") 
import provider.writes // makes the implicit visible here 
... 

(あなたがタイプに名前を付ける必要がある場合、または自分で)あなたは型変数を提供することにより、コンパイラを支援する必要があるかもしれません:

providers("length") match { 
    case provider: ResultProvider[a] => 
    import provider.writes 
    ... 
} 
+0

それは働いた!なぜあなたは型変数(つまり 'a')でコンパイラを助ける必要があるのか​​詳しく記述できますか?それ以外の場合は動作しません。 –

+0

残念ながら、これは私が理解していないコンパイラの型推論の詳細に依存します。私はちょうど前に似たような状況にあった。 –

関連する問題

 関連する問題