2016-04-16 32 views
2

我一直在尋找無形單例的細節,並遇到一個小例子,不能按預期方式工作。我認爲,只要我們通過一個單類型的方法中,應該有一個隱含的Witness.Aux [_]在可用範圍:編譯器無法找到隱式Witness.Aux [_]單身符號

import shapeless._ 
import syntax.singleton._ 

object SingletonTest extends App { 

    def check[K](a: K)(implicit witness: Witness.Aux[K]): Unit = { 
    println(witness.value) 
    } 

    val b = 'key.narrow 
    val c: Witness.`'key`.T = b 

    check(c) // Works! 
    check(b) /* Fails: shapeless.this.Witness.apply is not a valid implicit value     for shapeless.Witness.Aux[Symbol with shapeless.tag.Tagged[String("key")]] because: 
       hasMatchingSymbol reported error: Type argument Symbol with shapeless.tag.Tagged[String("key")] is not a singleton type */ 
} 

我期望類型的b和c中的例子中,以是一樣的(並用=:=檢查它是否成功)。如果我添加一個隱含的見證人[Witness。手動將代碼編譯爲'key .T]。

環境:斯卡拉2.11.8; Shapeless 2.3.0

回答

4

解釋是Scala編譯器會在推斷左側val的類型時在右側擴展單例類型......您將在Scala的the relevant section中找到章節和章節語言規範。

下面是同一現象的獨立於無形的例子,

scala> class Foo ; val foo = new Foo 
defined class Foo 
foo: Foo = [email protected] 

scala> val f1 = foo 
f1: Foo = [email protected] 

scala> val f2: foo.type = foo 
f2: foo.type = [email protected] 

正如你可以從f2定義Scala編譯器知道該值foo有更精確的類型foo.type(即單身看但是,除非明確要求,否則不會推斷出更精確的類型。相反,它會推斷非單例(即加寬)類型Foo,正如您在f1的情況下所看到的那樣。請參閱this related answer

相關問題