2016-03-17 66 views
3

我用無形的情況下級轉化, 我有2例類:不成形的情況下級轉化

import shapeless._ 

case class Foo(id: Int, name: String) 
case class Bar(id: Int, name: String, price: Double) 

val fooGen = Generic[Foo] 
val barGen = Generic[Bar] 

val foo = Foo(1, "foo") 
val fooRepr = fooGen.to(foo) 
val additional = fooRepr :+ 1.0 
val bar = barGen.from(additional) 

這工作得很好,但是當我嘗試轉換酒吧爲foo

fooGen.from(barGen.to(bar)) 

我得到一個錯誤:

found : main.barGen.Repr 
[error]  (which expands to) shapeless.::[Int,shapeless.:: [String,shapeless.::[Double,shapeless.HNil]]] 
[error] required: main.fooGen.Repr 
[error]  (which expands to) shapeless.::[Int,shapeless.::[String,shapeless.HNil]] 
[error] println(fooGen.from(barGen.to(bar)))  

是否有可能轉換一個案例類的地方比另一個更多?

回答

7

你如何調整FooHList表示類似的,通過添加元素,你必須調整的BarHList表示爲好,通過去除多餘的元素:

fooGen.from(barGen.to(bar).take(2)) 

take需要Nat參數,並且此行代碼使用從Int文字到Nat類型級自然數的隱式轉換。

你可以在HList s的shapeless.syntax.hlists.scala找到其他方法。

1

我的回答是基於Travis Brown先前的回答,對StackOverFlow有點類似的問題。

import shapeless._, ops.hlist._, ops.record._ 

class SameFieldConverter[T] { 
    def apply[S, SR <: HList, TR <: HList, MR <: HList, IR <: HList](s: S)(implicit 
     genS: LabelledGeneric.Aux[S, SR], 
     genT: LabelledGeneric.Aux[T, TR], 
     merger: Merger.Aux[SR, HNil, MR], 
     intersection: Intersection.Aux[MR, TR, IR], 
     align: Align[IR, TR]) = genT.from(intersection(merger(genS.to(s), HNil))) 
    } 
// defined class SameFieldConverter 

def convertTo[T] = new SameFieldConverter[T] 
//defined function convertTo 

case class Foo(one: String, two: Int, three: Boolean) 
// defined class Foo 

case class Bar(three: Boolean, one: String) 
// defined class Bar 

convertTo[Bar](Foo("One", 2, false)) 
// res26: Bar = Bar(false, "One") 
相關問題