Trying to find a way to "reshape" a case constructor to filling some default value. Is the following possible?
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)
Is it possible with shapeless or do we have to go the macro route?
It's possible to construct such reshaper almost without change in your code or custom typeclasses. We will just prepend argument lists and then align result to LabelledGeneric[MyClass]#Repr
:
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With