正在尝试创建HCons列表CaseClassShape [英] Trying to make a HCons List CaseClassShape

查看:0
本文介绍了正在尝试创建HCons列表CaseClassShape的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我想创建一个HListCaseClassShape,它将允许我创建超过22个长度限制的案例类。因此,从Stefan Zeiger的代码here开始。

final class HListShape[Level <: ShapeLevel, M <: HList, U <: HList : ClassTag, P <: HList](val shapes: Seq[Shape[_, _, _, _]]) extends MappedScalaProductShape[Level, HList, M, U, P] {
    def buildValue(elems: IndexedSeq[Any]) = elems.foldRight(HNil: HList)(_ :: _)
    def copy(shapes: Seq[Shape[_ <: ShapeLevel, _, _, _]]) = new HListShape(shapes)
}
implicit def hnilShape[Level <: ShapeLevel] = new HListShape[Level, HNil.type, HNil.type, HNil.type](Nil)
implicit def hconsShape[Level <: ShapeLevel, M1, M2 <: HList, U1, U2 <: HList, P1, P2 <: HList](implicit s1: Shape[_ <: Level, M1, U1, P1], s2: HListShape[_ <: Level, M2, U2, P2]) =
    new HListShape[Level, M1 :: M2, U1 :: U2, P1 :: P2](s1 +: s2.shapes)

然后我继续创建我的HListCaseClassShape:

class HListCaseClassShape[P <: Product, LiftedList, LiftedCaseClass <: P, PlainList, PlainCaseClass <: P](
       mapLifted: LiftedList => LiftedCaseClass, mapPlain: PlainList => PlainCaseClass)(
       implicit columnShapes: Shape[FlatShapeLevel, LiftedList, PlainList, LiftedList], classTag: ClassTag[PlainCaseClass])
  extends MappedScalaProductShape[FlatShapeLevel, P, LiftedCaseClass, PlainCaseClass, LiftedCaseClass] {
  val shapes = columnShapes.asInstanceOf[HListShape[_,_,_,_]].shapes
  override def toMapped(v: Any) = {
    val folded = v.asInstanceOf[Product].productIterator.foldRight(HNil: HList)(_ :: _)
    folded.asInstanceOf[PlainList]
  }
  def buildValue(elems: IndexedSeq[Any]) = {
    val list = elems.foldRight(HNil: HList)(_ :: _)
    mapLifted(list.asInstanceOf[LiftedList])
  }
  def copy(s: Seq[Shape[_ <: ShapeLevel, _, _, _]]) = new HListCaseClassShape(mapLifted, mapPlain) { override val shapes = s }
}

最后,我尝试实例化它

case class LiftedB(data1: Rep[String], data2: Rep[String], data3: Rep[String], data4: Rep[String], data5: Rep[String], data6: Rep[String], data7: Rep[String], data8: Rep[String], data9: Rep[String], data10: Rep[String], data11: Rep[String], data12: Rep[String], data13: Rep[String], data14: Rep[String], data15: Rep[String], data16: Rep[String], data17: Rep[String], data18: Rep[String], data19: Rep[String], data20: Rep[String], data21: Rep[String], data22: Rep[String], data23: Rep[String], data24: Rep[String], data25: Rep[String])
case class B(data1: String, data2: String, data3: String, data4: String, data5: String, data6: String, data7: String, data8: String, data9: String, data10: String, data11: String, data12: String, data13: String, data14: String, data15: String, data16: String, data17: String, data18: String, data19: String, data20: String, data21: String, data22: String, data23: String, data24: String, data25: String )

.然后是形状:

type DirectConsList = HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HCons[String, HNil]]]]]]]]]]]]]]]]]]]]]]]]]
type LiftedConsList = HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HCons[Rep[String], HNil]]]]]]]]]]]]]]]]]]]]]]]]]

implicit object BShape extends HListCaseClassShape[
  Product,
  LiftedConsList,
  LiftedB,
  DirectConsList,
  B](toLifted, toDirect)

def toLifted(list: LiftedConsList) = {
  list match {
    case data1 :: data2 :: data3 :: data4 :: data5 :: data6 :: data7 :: data8 :: data9 :: data10 :: data11 :: data12 :: data13 :: data14 :: data15 :: data16 :: data17 :: data18 :: data19 :: data20 :: data21 :: data22 :: data23 :: data24 :: data25 :: HNil => {
      LiftedB(data1, data2, data3, data4, data5, data6, data7, data8, data9, data10, data11, data12, data13, data14, data15, data16, data17, data18, data19, data20, data21, data22, data23, data24, data25 )
    }
    case _ => throw new Exception("malformed HList")
  }
}

def toDirect(list:DirectConsList) = {
  list match {
    case data1 :: data2 :: data3 :: data4 :: data5 :: data6 :: data7 :: data8 :: data9 :: data10 :: data11 :: data12 :: data13 :: data14 :: data15 :: data16 :: data17 :: data18 :: data19 :: data20 :: data21 :: data22 :: data23 :: data24 :: data25 :: HNil => {
      B(data1, data2, data3, data4, data5, data6, data7, data8, data9, data10, data11, data12, data13, data14, data15, data16, data17, data18, data19, data20, data21, data22, data23, data24, data25 )
    }
    case _ => throw new Exception("malformed HList")
  }
}

只有当我实例化并通过db.stream运行时,它才会引发异常:

Exception in thread "main" java.lang.ClassCastException: slick.collection.heterogeneous.HCons cannot be cast to com.example.CaseClassShapeQueryExample$B
  at com.example.CaseClassShapeQueryExample$$anonfun$2.apply(CaseClassShapeQueryExample.scala:106)
  at slick.backend.DatabasePublisher$$anon$3$$anonfun$onNext$1.apply(DatabasePublisher.scala:48)
  at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)

所以它得到了从查询返回的纯元组对象(即DirectConsList),但我不能将其转换为B对象。我做错了什么?

推荐答案

看起来我只遗漏了mapPlain(folded.asInstanceOf[PlainList])方法中的mapPlain(folded.asInstanceOf[PlainList])。HListCaseClassShape实现的工作方式如下:

class HListCaseClassShape[P <: Product, LiftedList, LiftedCaseClass <: P, PlainList, PlainCaseClass <: P](
       mapLifted: LiftedList => LiftedCaseClass, mapPlain: PlainList => PlainCaseClass)(
       implicit columnShapes: Shape[FlatShapeLevel, LiftedList, PlainList, LiftedList], classTag: ClassTag[PlainCaseClass])
  extends MappedScalaProductShape[FlatShapeLevel, P, LiftedCaseClass, PlainCaseClass, LiftedCaseClass] {
  val shapes = columnShapes.asInstanceOf[HListShape[_,_,_,_]].shapes
  override def toMapped(v: Any) = {
    val folded = v.asInstanceOf[Product].productIterator.foldRight(HNil: HList)(_ :: _)
    mapPlain(folded.asInstanceOf[PlainList])
  }
  def buildValue(elems: IndexedSeq[Any]) = {
    val list = elems.foldRight(HNil: HList)(_ :: _)
    mapLifted(list.asInstanceOf[LiftedList])
  }
  def copy(s: Seq[Shape[_ <: ShapeLevel, _, _, _]]) = new HListCaseClassShape(mapLifted, mapPlain) { override val shapes = s }
}

此外,此处还提供了GIST:HListCaseClassShape

这篇关于正在尝试创建HCons列表CaseClassShape的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆