2015-11-12 21 views
5

Bir varsayılan kurucuyu doldurmak için bir vaka yapıcısını "yeniden şekillendirmek" için bir yol bulmaya çalışın. Aşağıdakiler mümkün mü? Bir vaka sınıfı kurucusu yeniden şekillendiriyor musunuz?

def reshape[T, R1 <: HList, R2 <: HList](h: R1): R2 => T = ??? 

//example 
case class MyClass(a: Double, b: String, c: Int) 

val newConstructor = reshape[MyClass]('b ->> "bValue" :: HNil) 

newConstructor('a ->> 3.1 :: 'c ->> 4 :: HNil) 
res1: MyClass = MyClass(3.1, "bValue", 4) 

şekilsiz ile mümkün mü yoksa makro rota gitmek zorunda mısın?

cevap

7

Kodunuzda veya özel yazım öğelerinizde hemen hemen hiç değişiklik yapmadan yeniden biçimlendirmek mümkündür. Biz sadece prepend argüman listeleri olacak ve daha sonra align sonuç LabelledGeneric[MyClass]#Repr için:

import shapeless._ 
import syntax.singleton._ 
import ops.hlist._ 

class PartialConstructor[C, Default <: HList, Repr <: HList] 
(default: Default) 
(implicit lgen: LabelledGeneric.Aux[C, Repr]) { 
    def apply[Args <: HList, Full <: HList] 
    (args: Args) 
    (implicit prepend: Prepend.Aux[Default, Args, Full], 
    align: Align[Full, Repr]): C = 
    lgen.from(align(default ++ args)) 
} 

class Reshaper[C]() { 
    def apply[Default <: HList, Repr <: HList] 
    (default: Default) 
    (implicit lgen: LabelledGeneric.Aux[C, Repr]) = 
    new PartialConstructor[C, Default, Repr](default) 
} 

def reshape[C] = new Reshaper[C] 
+0

teşekkürler! Hazırla ve hizala, kesinlikle aradığım şey. – KailuoWang