2017-08-28 126 views
3

给定两个case class ES:具有相同形状的案例类?

case class Foo(x: Int) 
case class Bar(x: Int) 

使用shapeless,我怎么能确定是否FooBar具有相同的 “形”,即Int :: HNilHList

+1

'=:='不工作? –

回答

3

对于具体的case类,你可以这样做:

case class Foo(x: Int) 
    case class Bar(x: Int) 
    case class Baz(x: String) 

    implicitly[Generic.Aux[Foo, Int :: HNil]] 
    implicitly[Generic.Aux[Bar, Int :: HNil]] 
    implicitly[Generic.Aux[Baz, String :: HNil]] 

更通用的方法:

如果你喜欢用值,您可以创建功能工作:

def test[A, B, L <: HList](a: A, b: B)(implicit 
             gen1: Generic.Aux[A, L], 
             gen2: Generic.Aux[B, L]): Int = 42 

    val foo = Foo(1) 
    val bar = Bar(2) 
    val baz = Baz("a") 

    test(foo, bar) // compiles 
// test(foo, baz) // doesn't compile 

如果你喜欢使用您可以创建的类型类型:

trait SameShape[A, B] 

    object SameShape { 
    implicit def mkSameShape[A, B, L <: HList](implicit 
               gen1: Generic.Aux[A, L], 
               gen2: Generic.Aux[B, L] 
               ): SameShape[A, B] = 
     new SameShape[A, B] {} 
    } 

    implicitly[SameShape[Foo, Bar]] // compiles 
// implicitly[SameShape[Foo, Baz]] // doesn't compile 
5

A, B如果存在形状S具有相同的形状,使得SAB的通用表示。这直接转化为以下功能:

trait SameShape[A, B] 

object SameShape { 
    implicit def instance[A, B, S] 
    (implicit a: Generic.Aux[A, S], b: Generic.Aux[B, S]): SameShape[A, B] = 
     new SameShape[A, B] {} 
} 
+1

我猜在这种情况下返回类型甚至没有关系。 – Haspemulator

+0

很确定你的意思是'def'而不是'val'。 –

+0

另外,'Generic'只有一个类型参数。您可能需要'Generic.Aux' –

相关问题