2015-01-16 10 views
5

kullanarak yöntem için gerekli olandan daha fazla kanıt gerekli Dün birkaç meslektaşla Shapeless'ı araştırıyordum ve bu parametre Int:Shapeless

mutlaka o E :: T =:= Int :: T sonucuna varılabilir, ancak derleyici bunun gerçekleştirilebilmesi mümkün değildi -
def addOneToCaseClass[C, H <: HList, E, T <: HList] 
    (c: C) 
    (implicit gen: Generic.Aux[C, H], 
       h: IsHCons.Aux[H, E, T], 
       ev: E =:= Int, 
       ev2: (Int :: T) =:= H 
    ): C = { 

    val hList = gen.to(c) 

    val elem = hList.head 
    val tail = hList.tail 

    val newElem = elem + 1 

    gen.from(newElem :: tail) 
} 

o ev2 parametre gereksiz geliyor bana.

Neden belli bir nedeni var mı?

+0

Bu hiçbir şekilde sorunuza cevap vermez, ancak E'den tamamen kurtulursa işe yarıyor mu? [C, H, T], 'IsHCons.Aux [H, Int, T], vb? E hala mevcutken, h', 'ev' ve' ev2''nün herhangi biri işe yaramalı? – ellisbben

cevap

2

Sezgileriniz makul, ancak ne yazık ki, Scala derleyicisi ve ev'dan ev2 türetmek için yeterince akıllı değildir. Sorun, h'un yalnızca H'un E :: T'a ayrıştığını belirlemesidir; bu, E ve T eşittir H eşittir.

Ben senin orijinaline benzer ile gelip, ama bir daha tanık vardır edebilirsiniz Bunun tersest formülasyonu, İşte

def addOneToCaseClass[C, R <: HList, T <: HList](c: C) 
    (implicit 
    gen: Generic.Aux[C, R], 
    h: IsHCons.Aux[R, Int, T], 
    ev: (Int :: T) =:= R) = { 
    val hList = gen.to(c) 
    val elem = hList.head 
    val tail = hList.tail 
    gen.from(elem+1 :: tail) 
} 

biz E =:= Inth kullanarak göstermek için kanıt ortadan edebiliyoruz

Bu R, Int :: T'a ayrışır. Yine de, gen'da güncellenen öğelerle geri dönmek için Int :: T'un R'a eşit olduğunu göstermemiz gerekiyor.

+0

Cevabımı kaldırmam gerekti ve umarım bu yorum yönetim tarafından silinmeyecektir (önceki gibi). Öyleyse neden hala “R” (aslında derleme) yerine '(Int :: T)' yerine koymak yerine ek eşitlik kullanmak zorundayız. Çünkü [bu göç belgesi] (https://github.com/milessabin/shapeless/wiki/Migration-guide:-shapeless-1.2.4-to-2.0.0#iso-is-now-generic) bize örnek vermeden '=: =': 'def makeFoo [L <: HList] (l: L) (örtük fooGen: Generic.Aux [Foo, L]): Foo = fooGen.from (l)' ve açıkça bunun imkansız olduğunu söylüyor. ama 'Bu sınırlama Scala 2.11' de gidecek – dk14