2015-08-18 24 views
0

我想知道給定的case class中是否存在特定的類成員。避免具有無形替代的結構類型

以下確實給了我答案,在編譯時失敗是正確的。 (信貸特拉維斯布朗)

scala> def getIntId[A, R <: HList](a: A)(implicit 
| gen: LabelledGeneric.Aux[A, R], 
| sel: Selector.Aux[R, Witness.`'id`.T, Int] 
|): Int = sel(gen.to(a)) 

case class Foo(id: String) 
case class Bar(id: Int, name: String) 

scala> getIntId(Bar(123, "bar")) 
res3: Int = 123 

scala> getIntId(Foo("12345")) 
<console>:15: error: could not find implicit value for parameter sel: shapeless.ops.record.Selector.Aux[R,Symbol with shapeless.tag.Tagged[String("id")],Int] 
      getIntId(Foo("12345")) 

現在,如果我沒有一個具體的類型,但是T通入getIntId方法,有沒有辦法讓這個與泛型類型T工作?

更新 說有一個名爲findIdFromType方法如所描述的,其取入T型(其中T總是會有一些case class)所示。是否有可能做到這一點?

def findIdFromType[T](t:T) = { 
    getIntId(t) //as expected doesn't compile 
} 
+0

我不確定我明白你的意思,你能提供一個用例作爲例子嗎? –

+0

@ GabrielePetronella:我剛剛更新了問題(更新部分)。讓我知道是否需要進一步擴展它?謝謝。 –

回答

2

getIntId需要兩個隱式參數。

如果您需要在本地方法的上下文中調用它,則需要證明這些參數存在於此類上下文中。

爲了做到這一點,你必須傳播隱含的證據,這樣

def findIdFromType[A, R <: HList](a: A)(implicit 
    gen: LabelledGeneric.Aux[A, R], 
    sel: Selector.Aux[R, Witness.`'id`.T, Int]): Int = getIntId(a) 

這當然是完全無用的例子,但如果你要執行的包裝方法中的其它操作,這是要走的路:傳播隱含的證據。

相關問題