2013-06-04 14 views
5

私は、次の動作の理解を取得しようとしています:Scalaの型の境界&分散

scala> class C[-A, +B <: A] 
<console>:7: error: contravariant type A occurs in covariant position 
        in type >: Nothing <: A of type B 
     class C[-A, +B <: A] 
        ^

ただし、次の作品:

scala> class C[-A, +B <% A] 
defined class C 

私はから問題があるかもしれないことがわかりますバウンディング変数とバウンド変数の分散は逆ですが、具体的な問題が何であるかはっきりしていません。 ビューバインドにバインドされた型を変更すると、問題が解決されるのはなぜか分かりません。適用可能な暗黙的な変換がない場合、私は2つの定義がほぼ同じ効果を持つと期待します。何かがあれば、いたずらのためのより多くの機会を提供するための視界が期待されます。

私は機能のようないくつかの点であるクラスを定義する背景のビットのために

、と私は間違いなく

CompositeFunc[-A, +B <: C, -C, +D] (f1 : BaseFunc[A, B], f2 : BaseFunc[C, D]) 
    extends BaseFunc[A, D] 

CompositeFunc[-A, +B <% C, -C, +D] (f1 : BaseFunc[A, B], f2 : BaseFunc[C, D]) 
    extends BaseFunc[A, D] 

のようなものをやってみたかったが、実際に好適であるが、私はまだだろうここで何が起こっているのかをよく理解してください。まず簡単なもの

+0

興味をそそる...私は1時間を費やしたとえばタイプを探してタイプバインドで安全が壊れます。見つかったものがありません: – gzm0

+0

また、バインドされていないサンプルがあった場合は、ビューバインドでどのように置換すれば解決するのか分かりにくいです。 –

+0

はい、私は幾分同意します。しかし、基本的な違いは、 (少なくとも私の直感は...) – gzm0

答えて

4

class C[-A, +B <% A] 

これはview以来

class C[-A, +B](implicit view: B => A) 

と同等ですが公に返されていない、それはAまたはBの分散を制約することになる位置にありません。例えば。言い換えれば

class C[-A, +B](val view: B => A) // error: B in contravariant position in view 

C[-A, +B <% A]は制約の面でC[-A, +B]よりも違いはありません、ビューの引数は何も変わりません。


上限ケースC[-A, +B <: A]わかりません。 §4.5状態のスカラ言語仕様

型宣言または型パラメータの下限の分散位置は、型宣言またはパラメータの分散位置の逆です。

Bの分散が関与していないようですが、一般的に上限は共変でなければなりません:

trait C[-A, B <: A] // contravariant type A occurs in covariant position 

これは何とか問題を生成しなければなりませんか?しかし、私は、この構成が特定のケースでは不安定になることを証明する例を思い付くことができませんでした....合成機能については


は、なぜちょうど

class Composite[-A, B, +C](g: A => B, h: B => C) extends (A => C) { 
    def apply(a: A) = h(g(a)) 
} 

EDITません:たとえば:

import collection.LinearSeq 

def compose[A](g: Traversable[A] => IndexedSeq[A], h: Traversable[A] => LinearSeq[A]) = 
    new Composite(g, h) 
+0

興味深いことに、感謝します。私は 'trait C 'を試したとは思わなかった –

+0

はい、それらは 'Function1'の分散のため正確に作成されます –

+0

class' CompositeFunc [-A、B、+ C] '[-A、B <:A]'両方のオーダーで完全な意味があるとしても、 'g:BaseFunc(Traversable [A]、LinearSeq [A]) 'を使って' f:BaseFunc(Traversable [A]、IndexedSeq [A]) 'を作成することはできません。 –

関連する問題