HList元素匹配类型类的类型参数

时间:2018-06-06 14:19:57

标签: scala shapeless

我尝试使用Shapeless实现与Slick的表和列定义类似的东西。

此代码将与第三方Java库一起使用,因此在某些时候我需要将HList转换为Array[Any]

即使后面的内容似乎有效,但它看起来并不是正确的方法:

import shapeless._
import ops.hlist._

trait ColumnType[A]

object ColumnType {
  implicit object StringType extends ColumnType[String]
  implicit object IntType extends ColumnType[Int]
  implicit object BooleanType extends ColumnType[Boolean]
}

case class Column[T : ColumnType](name: String, description: String)

trait Logger[L <: HList] {
  val columns: L

  object javaTypes extends Poly1 {
    implicit def caseInt = at[Int](i => new java.lang.Integer(i))
    implicit def caseString = at[String](identity)
    implicit def caseBoolean = at[Boolean](b => new java.lang.Boolean(b))
  }

  object extract extends Poly1 {
    implicit def caseT[T : ColumnType] = at[Column[T]](_.asInstanceOf[T])
  }

  def apply[P <: Product, M <: HList](p: P)(
    implicit
    gen: Generic.Aux[P, L],
    mapper: Mapper.Aux[javaTypes.type, L, M]
  ): List[Any] = gen.to(p).map(javaTypes).runtimeList
}

Logger定义如下:

class AccessLog extends Logger[String :: Int :: Boolean :: HNil] {
  val path = Column[String]("path", "uri path")
  val statusCode = Column[Int]("statusCode", "status code")
  val authenticated = Column[Boolean]("authenticated", "is user authenticated")

  val columns = HList(path, statusCode, authenticated).map(extract)
}

将被使用:

val accessLog = new AccessLog

accessLog("1", 2, false).foreach(p => println(s"$p: ${p.getClass}"))

要求是columns的类型应该与Logger的类型参数匹配,也是将传递的值转换为Java类型的方法。

我对定义extract的方式特别不安。

0 个答案:

没有答案