6

次の動作をよりよく理解しようとしています。

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]

実際には望ましいですが、ここで何が起こっているのかをよりよく理解したいと思います。

4

1 に答える 1

4

まず簡単なもの:

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

これは、

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

は公開されていないため、またはviewの分散を制限する立場にはありません。例えばAB

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

言い換えれば、制約に関してはC[-A, +B <% A]違いはなく、view 引数は何も変更しません。C[-A, +B]


C[-A, +B <: A]よくわからない上限のケース。§4.5 の Scala 言語仕様には次のように記載されています。

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

の分散は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))
}

編集:例:

import collection.LinearSeq

def compose[A](g: Traversable[A] => IndexedSeq[A], h: Traversable[A] => LinearSeq[A]) =
  new Composite(g, h)
于 2013-06-04T21:37:52.400 に答える