2012-06-14 21 views
7

我試圖用無形的方式以類型安全的方式輕鬆地堆積對象。無形:前置。隱含未找到

問題是當我想連續(:::)兩個HList。我遇到了一個新手(似乎至少)的問題。它在上下文中忽略了一個隱含的實例Prepend

但是,看着hlist.scala,我可以看到,在對象PrependPrependAux中定義了通用implicit def

添加import Prependimport PrependAux手動沒有改變任何東西(顯然是......)。

所以這裏的代碼減少到最低限度:

enter code here 

import shapeless._ 
import HList._ 
import Prepend._ 
import PrependAux._ 

object test { 

    val a:HList = 1 :: 4 :: "A" :: HNil 
    val b:HList = "R" :: false :: HNil 

    val c:HList = a ::: b // <<<<<<<<<<< NEEDS A Prepend in the context 

} 

在現在控制檯:

[error]  test.scala:10: could not find implicit value for parameter prepend: shapeless.Prepend[shapeless.HList,shapeless.HList] 
[error]  val c:HList = a ::: b // this needs an implicit Prepend in the current context 

我應該燒我的眼睛嗎?

感謝

編輯

一個小更新來重新complexify了一下真正的問題,因爲之前庸俗化爲強。

這裏是什麼樣的事情,我將能夠做到:

case class A[L<:HList](a:L) { 
    def doSmth[C <:HList](c:C) = a ::: c 
} 

所以我沒有進入真正的類型,只有我自己知道,他們是HList秒。

+0

唯一的答案是更新也。它仍然有效。在我的解決方案中缺少的東西顯然是scalac選項... –

回答

10

上傳到HList是這裏的問題。幾乎沒有任何東西可以用簡單的老式HList(除了添加新的元素)。

您可以提供更多的信息類型的註釋:

val a: Int :: Int :: String :: HNil = 1 :: 4 :: "A" :: HNil 
val b: String :: Boolean :: HNil = "R" :: false :: HNil 
val c: Int :: Int :: String :: String :: Boolean :: HNil = a ::: b 

或者只是讓類型推斷,這通常是方便多了:

val a = 1 :: 4 :: "A" :: HNil 
val b = "R" :: false :: HNil 
val c = a ::: b 

在回答您的意見:如果你確定自己有需要的證據,你可以做你想做的事(注意,我認爲a: Aa: L的錯字, T優需要-Ydependent-method-types這個工作):

case class A[L <: HList](a: L) { 
    def doSmth[C <: HList](c: C)(implicit p: Prepend[L, C]) = a ::: c 
} 

一般來說,你可以看看這是必要的,你正在使用的操作,然後將它們包括在你的方法implicits。

+0

Thx,你是完全正確的(所以我當然驗證了)。其實我的例子減少了太多的問題。因爲我的問題存在於某種東西中(減少一點):'case class A [L <:HList](a:A){def doSmth [C <:HList](c:C)= a ::: c}'。有什麼想法? –

+0

@andypetrella:我已編輯解決您的問題。 –

+0

你是錯的!對於那個很抱歉。 Thx的更新(我會更新問題)。其實我是這麼做的,可能我需要你提到的選項才能實現這個功能。 Thx再次,我會盡快試一試。 –