:たとえば
ポイント。
trait UberSomething {
def name: String
}
// these maybe in different files
case class Something(name: String) extends UberSomething
case class SomethingOther(name: String) extends UberSomething
import shapeless._, ops.hlist.Align
私は前のStackOverflow上のどこかに見てきた別のアプローチ、ストリートクレドを盗むために謝罪しては、フィールドの順序は重要ではないだろうとAlign
などを使用することです。
class Convert[Target] {
def apply[Source, HLS <: HList, HLT <: HList](s: Source)(implicit
// Convert the Source to an HList type
// include field names, e.g "labelled"
// Shapeless "generates" this using an implicit macro
// it looks at our type, extracts a list of (Name, Type) pairs
genS: LabelledGeneric.Aux[Source, HLS],
// Convert the Target o an HList type
// include field names, e.g "labelled"
// So again we have a (Name, Type) list of pairs this time for Target
genT: LabelledGeneric.Aux[Target, HLT],
// Use an implicit align to make sure the two HLists
// contain the same set of (Name, Type) pairs in arbitrary order.
align: Align[HLS, HLT]
) = genT from align(genS to s)
}
// Small trick to guarantee conversion only requires
// a single type argument, otherwise we'd have to put something
// in place for HLS and HLT, which are meant to be path dependant
// and "calculated" by the LabelledGeneric.Repr macro so it wouldn't work as it breaches the "Aux pattern", which exposes a type member materialized by a macro in this case.
// HLT and HLS come from within genS.Repr and genT.Repr.
def convert[T] = new Convert[T]
あなた自身をつまずかないようにHList
paramsをうまくapply
の一部としてマスクされているので、これは少し良いです。
val sample = Something("bla")
convert[SomethingOther](sample) // SomethingOther("bla")
この行は、genT from align(genS to s)
です。
型崩れは間違いなくこれを行うことができ、http://stackoverflow.com/questions/23192760/safely-copying-fields-between-case-classes-of-different-types –
おかげで、このルックスを見て有望な – Sofia