2012-01-02 1 views
6

特性の型パラメータの制約を緩和し、それらをエビデンスパラメータの形式でメソッドに追加したいとします。いくつかの骨格セットアップを考える:エビデンスパラメータの型パラメータの上限を交換する

trait StateX[Repr <: StateX[Repr]] extends State[Repr] { 
    protected def reader: Reader[Repr] 
    def observe: Observer[Repr] = Observer(reader) 
} 

をそして、これはそうではない:

trait State[Repr] 
object Observer { 
    def apply[Repr <: State[Repr]](reader: Reader[Repr]): Observer[Repr] = 
    new Observer[Repr] {} 
} 
trait Observer[A] 
trait Reader [A] 

これは動作します

trait StateY[Repr] extends State[Repr] { 
    protected def reader: Reader[Repr] 
    def observe(implicit ev: Repr <:< State[Repr]): Observer[Repr] = Observer(reader) 
} 

メッセージ"inferred type arguments [Repr] do not conform to method apply's type parameter bounds [Repr <: State[Repr]]"で。証拠evはこのコンホメーションを示唆しているので、どのようにしてStateYを修正できるのだろうと思います。

答えて

6
あなたの問題は、フォーム A <:< Bの証拠はタイプ Aの値はタイプ Bの値に変換することができることを意味していても、それは型制約を使用するための A <: B ...確かに、主な理由を示すものではありませんということです

このようなサブタイプの関係が成り立たないため、通常のタイプ・バインドではなくビュー・バインドが正確に行われます。

したがってStateYRepr <:< State[Repr]における制約は、Observerapply方法で結合Repr <: State[Repr]を満たすのに十分ではありません。 StateXの型パラメータの制約を緩和したい場合、唯一の方法は、対応するapplyメソッドの型パラメータの制約を弱めることです。それはあなたが、むしろ全体の制約を使用したい場合は、

object Observer { 
    def apply[Repr <% State[Repr]](reader : Reader[Repr]) : Observer[Repr] = 
    new Observer[Repr] {} 
} 

または代わりに、

object Observer { 
    def apply[Repr](reader : Reader[Repr]) 
       (implicit ev : Repr <:< State[Repr]) : Observer[Repr] = 
    new Observer[Repr] {} 
} 

をバインド通常タイプの代わりにバインドビューを使用して、次のようなものを取得します。

5

ReprState[Repr]に変換できることが示されています。それはリーダー[Repr]で何ができるかについて何も言わない。

A => Bの場合、T [A]をT [B]に変換する一般的な方法はありません(Tとは独立しています)。これは共変Tでも可能ですが、言語にそのようなものはありません。

関連する問題