2014-10-06 156 views
8

假設我有:斯卡拉:使用類型參數或抽象類型,類型限制

class Bounded[A] { 
    type apply[C <: A] = C 
} 

這編譯:

implicitly[Bounded[Any]#apply[String] =:= String] 

這種失敗:

type Str = Bounded[Any]#apply[String] 

...有:

[error] /home/grant/Workspace/scunits/test/src/main/scala/Box.scala:37: type arguments[String] do not conform to type apply's type parameter bounds [C <: A] 
[error] type Str = Bounded[Any]#apply[String] 
[error]       ^

我嘗試使用抽象類型而不是類型參數,結果相同。我發現的唯一解決方法是實例化類型。這將編譯:

val boundedAny = new Bounded[Any] 
type Str2 = boundedAny.apply[String] 

不幸的是,我用不具有性能方面的原因運行時間的情況下,往往幻影類型的工作。

爲什麼Scala會在這裏產生編譯錯誤?有更好的解決方法嗎?

感謝您的任何幫助。

更新:除了下面的解決方法,我需要一種方法來覆蓋具有抽象類型邊界的類型。我這樣做,像這樣:

object Test { 
    class AbstractBounded[A] { 
    type apply[C <: A] <: A 
    class Workaround[C <: A] { 
     type go = apply[C] 
    } 
    } 
    class Bounded[A] extends AbstractBounded[A] { 
    type apply[C <: A] = C 
    } 

    type Str = Bounded[Any]#Workaround[String]#go 
} 

回答

1

如何:

scala> class Bounded[A] { class i[C <: A]{ type apply = C}} 
defined class Bounded 

scala> type TTT = Bounded[Any]#i[String]#apply 
defined type alias TTT 

scala> implicitly[TTT =:= String] 
res4: =:=[TTT,String] = <function1> 

斯卡拉結合參數輸入別名之前忘了查找通用(或另一種「抽象」類型)。鑑於=:=正常工作 - 對我來說看起來像一個錯誤。也許implicits正在解決另一個編譯級別或者在這個檢查之前。

+0

謝謝,這個bug對我來說是很多挫折的源頭。 – Grant 2014-10-14 23:38:09