2010-03-16 79 views
32

@uncheckedVariance可用於彌合Scala的聲明網站方差註釋和Java不變泛型之間的差距。什麼時候在Scala中需要@uncheckedVariance,爲什麼它在GenericTraversableTemplate中使用?

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] 

此註釋的有效用途是什麼?

+0

大問題! – 2010-03-16 21:54:23

回答

25

問題是GenericTraversableTemplate使用兩次:一次是可變集合(其類型參數應該是不變的),一次是不可變集合(協變總是爲王)。

GenericTraversableTemplate的類型檢測假設A類型參數爲協方差或不變量。然而,當我們以可變特質繼承它時,我們必須選擇不變性。相反,我們想在不可變子類中使用協方差。

因爲我們不能抽象GenericTraversableTemplate中的方差註釋(還;-)),所以我們可以根據子類將它實例化爲任一個,我們必須求助於轉換(@uncheckVariance本質上是一個那種鑄)。如要進一步瞭解,我建議我的論文(對不起;-)),或者我們最近bitrot paper

+0

謝謝!上週我很喜歡閱讀紙質書,但它並沒有專門處理將共同和不同版本的收藏整合到一個共同父母的問題。我想我會看看你的論文中有什麼:) – retronym 2010-03-16 16:19:15

+0

那麼,這主要是一個無恥的插件 - 我的論文並不直接處理這個確切的問題。儘管如此,它應該對這種更強大的多態性有更多的思考。我會在下面添加更多的想法。 – 2010-03-17 09:42:14

+0

「總是國王」......哈哈 – 2014-11-28 23:43:15

8

在我的論文我描述了一個微積分,Scalina,是有一定的限度&方差註解作爲一種語言的一部分(早期版本也可作爲workshop paper獲得)。這個討論的相關性是我想要開發這個微積分的下一個步驟:在其上創建另一個層,這樣你就可以抽象超越範圍(容易)和差異註釋(讓我的頭腦旋轉)。實際上,你不會只在這裏增加一個額外的圖層,而是泛化你的多態構造,使它們在各個層次上工作,並將你的「屬性」(邊界,變異註釋,需要的隱式參數......)變成常規類型有特殊的種類,都是抽象的。

Edsko de Vries在唯一性類型的上下文中很好地解釋了「屬性是類型」的思想。

Uniqueness Typing Simplified, Edsko德弗里斯,里納斯Plasmeijer,大衛亞伯拉罕。 在奧拉夫Chitil,佐爾坦霍瓦特和維多利亞Zsók(編輯):2007年 IFL,LNCS 5083,頁201-218,2008年

摘要:本文提出了一種獨特 類型系統比兩個 清潔的更簡單唯一性系統和我們之前提出的系統 。新的 類型系統很容易實現 實現並添加到現有的 編譯器,並可以很容易地擴展 與先進的功能,如較高的 排名類型和impredicativity。我們 描述了我們在Morrow中的實現, 具有這兩個特徵的實驗功能語言 。最後,我們 證明核心類型 系統相對於 按需調用lambda微積分的可靠性。

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(); 
     () 
     } 
     } 
    } 
    } 
相關問題