40

@uncheckedVarianceScala の宣言サイト分散アノテーションと Java の不変ジェネリックの間のギャップを埋めるために使用できます。

scala> import java.util.Comparator    
import java.util.Comparator

scala> trait Foo[T] extends Comparator[T]
defined trait Foo

scala> trait Foo[-T] extends Comparator[T]     
<console>:5: error: contravariant type T occurs in invariant position in type [-T]java.lang.Object with java.util.Comparator[T] of trait Foo
       trait Foo[-T] extends Comparator[T]
             ^

scala> import annotation.unchecked._    
import annotation.unchecked._

scala> trait Foo[-T] extends Comparator[T @uncheckedVariance]    
defined trait Foo

これは、java.util.Comparator が自然に反変であることを示しています。つまり、型パラメーターはパラメーターTに表示され、戻り値の型には表示されません。

ここで疑問が生じます: Java インターフェイスから拡張されていない Scala コレクション ライブラリでも使用されるのはなぜですか?

trait GenericTraversableTemplate[+A, +CC[X] <: Traversable[X]] extends HasNewBuilder[A, CC[A] @uncheckedVariance]

この注釈の有効な用途は何ですか?

4

3 に答える 3

29

問題は、GenericTraversableTemplate が 2 回使用されることです。1 回は可変コレクション (その型パラメーターは不変である必要があります) 用で、もう 1 回は不変コレクション (共分散が常に王様です) 用です。

GenericTraversableTemplate の型チェックは、A 型パラメーターの共分散または不変性を想定しています。ただし、可変トレイトで継承する場合は、不変性を選択する必要があります。逆に、不変のサブクラスでは共分散が必要です。

GenericTraversableTemplate のバリアンス アノテーション (まだ ;-)) を抽象化できないため、サブクラスに応じていずれかのアノテーションをインスタンス化できたので、キャストに頼る必要があります (@uncheckVariance は本質的に親切なキャストです)。 . さらに読むには、論文 (申し訳ありません ;-)) または最近のbitrot 論文をお勧めします。

于 2010-03-16T13:36:49.313 に答える
8

私の論文では、一種の言語の一部として境界と分散の注釈を持つ微積分、Scalina について説明しています (以前のバージョンは、ワークショップ ペーパーとしても入手できます)。この議論との関連性は、この微積分を開発する上で私が取りたい次のステップです。その上に別のレイヤーを構築して、オーバーバウンド (簡単) と分散注釈 (頭が回転します) を抽象化できるようにします。実際には、そこに 1 つのレイヤーを追加するだけでなく、ポリモーフィズム構造を一般化してすべてのレベルで機能するようにし、「属性」(境界、分散注釈、必要な暗黙の引数など) を通常の型にします。すべて抽象化の対象となる特殊な種類を使用します。

「属性は型である」という考えは、Edsko de Vries によって一意性の型の文脈でうまく説明されています。

Uniqueness Typing Simplified、Edsko de Vries、Rinus Plasmeijer、および David Abrahamson。Olaf Chitil、Zoltan Horváth、Viktória Zsók (編): IFL 2007、LNCS 5083、pp. 201-218、2008。

要約: Clean の一意性システムと以前に提案したシステムの両方よりも単純な一意性型システムを提示します。新しい型システムは簡単に実装して既存のコンパイラに追加でき、上位の型や非反復性などの高度な機能で簡単に拡張できます。これらの両方の機能を備えた実験的な関数型言語である Morrow での実装について説明します。最後に、call-by-need ラムダ計算に関してコア型システムの健全性を証明します。

于 2010-03-17T09:47:40.623 に答える
5

@uncheckedVarianceが使用されている別の機会を見つけました-抽象型のパラメーターのデフォルト値を返す合成メソッド:

M:\>scala -Xprint:typer -e "class C { def p[T >: Null](t: T = null) = t }"
[[syntax trees at end of typer]]// Scala source: (virtual file)
package <empty> {
  final object Main extends java.lang.Object with ScalaObject {
    def this(): object Main = {
      Main.super.this();
      ()
    };
    def main(argv: Array[String]): Unit = {
      val args: Array[String] = argv;
      {
        final class $anon extends scala.AnyRef {
          def this(): anonymous class $anon = {
            $anon.super.this();
            ()
          };
          class C extends java.lang.Object with ScalaObject {
            <synthetic> def p$default$1[T >: Null <: Any]: Null @scala.annotation.unchecked.uncheckedVariance = null;
            def this(): this.C = {
              C.super.this();
              ()
            };
            def p[T >: Null <: Any](t: T = null): T = t
          }
        };
        {
          new $anon();
          ()
        }
      }
    }
  }
于 2010-03-24T09:48:05.743 に答える