次の行を、=の左側と右側の2つの別個の部分として見る必要があります。
val oB: Option[B] = collectFirstOf(List(new A,new B))
ここで期待しているのは、collectFirstOf式の型(右辺値)は、値oBの型から推測される必要があるということです。コンパイラはこれを行うことができません。あなたはあなたが期待しているタイプを具体的に言わなければなりません。次の例を見てください。
val v: Long = 1 + 4
式1+4のタイプはIntです。次に、このintはLongに変換されます。コンパイラーは、1または4を長くしたいことを推測できません。
したがって、問題を修正するには、予期しているタイプをコンパイラーに通知する必要があります。そうでない場合は、java.lang.Objectを想定します。
val oB = collectFirstOf[B](List(new A,new B))
したがって、マニフェストは正しく割り当てられ、すべてが世界に順調に進んでいます。では、なぜ以下もコンパイルされるのでしょうか。
val oB:Option[B] = collectFirstOfT(List(new A,new B))
oB: Option[B] = Some(A@10f3a9c)
一見すると、これは機能するはずではないように見えますが、機能します。これは、collectFirstOfTが実際にOption [Nothing]を返すためです。これは、Option[B]に安全に変換できます。
scala> val f = collectFirstOfT(List(new A,new B))
f: Option[Nothing] = Some(A@baecb8)
scala> f.asInstanceOf[Option[B]]
res4: Option[B] = Some(A@baecb8)