具有相同形状的案例类?

时间:2017-08-28 18:44:55

标签: scala shapeless

给出两个case class es:

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

使用shapeless,如何确定FooBar是否具有相同的"形状",即Int :: HNilHList

2 个答案:

答案 0 :(得分:5)

AB如果存在形状S则具有相同的形状,SA和{{1}的通用表示形式}。这直接转换为以下函数:

B

答案 1 :(得分:3)

对于特定的案例类,您可以这样做:

  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