2014-10-16 40 views
4

我試圖爲類型類列表提供不同的實現集,其中導入不同的包對象會給最終用戶一個TypeClass實現的不同版本進入作用域,交換是完全不可見的。類型類和包對象的奇怪的隱式解析行爲

trait TypeClass[T] { 
    def name: String 
} 


trait DefaultTypeClasses { 
    implicit val String: TypeClass[String] 
    implicit val Int: TypeClass[Int] 
} 

trait FirstImplementor extends DefaultTypeClasses { 
    implicit object String extends TypeClass[String] { 
    def name = "test" 
    } 

    implicit object Int extends TypeClass[Int] { 
    def name = "int" 
    } 
} 

object FirstImplementor extends FirstImplementor 


object Test { 

    import FirstImplementor._ 

    def doSomething[T : TypeClass](value: T): Unit = { 
    println(implicitly[TypeClass[T]].name) 
    } 

    doSomething("test") 

} 

上述工作不如預期,但如果這樣做:

trait DefaultDefinitions extends DefaultTypeClasses { 
} 
package object something extends DefaultDefinitions with FirstImplementor {} 

然後我導入同一package objectTest對象的範圍,就像這樣:

import com.blabla.something._ // should bring all type class definitions from FirstImplementor into scope. 

object Test { 

    def doSomething[T : TypeClass](value: T): Unit = { 
    println(implicitly[TypeClass[T]].name) 
    } 

    doSomething("test")// Cannot find implicit value for TypeClass[String] 
    doSomething[String]("test")(String) // if passed explicitly it compiles as expected, no more imports necessary. 
} 

對於無論什麼原因,物化類型類都可以在顯式範圍內按名稱使用,但不在隱式範圍內。聽起來像我對SLS的知識正在經歷一個缺口,誰能澄清?

+0

測試也在包的東西?如果是這樣導入東西._不是必需的,它爲我編譯成功 – 2014-10-16 22:28:36

+0

我移動測試到其他包後我得到了同樣的問題 – 2014-10-16 22:32:18

+0

import something.String解決問題 – 2014-10-16 22:36:53

回答

1

但是,如果你在包中創建Implicits對象,它工作正常。不過,我不知道如果原始錯誤是一個錯誤在scalac或正確的行爲

package object something { 
    object Implicits extends DefaultDefinitions with FirstImplementor 
} 

import something.Implicits._ 
+0

它似乎更像是一個關於包對象的限制。但建議的方法,不管那個bug或限制,都很好,你可以在整個地方看到它(在許多Scala庫中),以便將隱式轉換帶入上下文。 – 2014-10-20 15:20:11