具有编译查询的通用特征

时间:2018-12-16 11:20:36

标签: scala slick

我正在尝试创建一个具有通用函数的特征,该特征返回一个光滑的Query并具有已编译的该函数的值,如下所示:

trait fn1[A1, E, U, C[_]] {
  protected def asc(a1: A1): Query[E, U, C]

  val Asc = Compiled(asc _)
}

但是当我尝试编译时,出现此错误:

Computation of type A1 => test.this.profile.api.Query[E,U,C] cannot be compiled (as type C)
val Asc = Compiled(asc _)

因为scala无法推断compilable: Compilable[V, C]的隐式参数Compiled.apply

问题在于类型参数A1,确实可以毫无问题地进行编译:

trait fn1[E, U, C[_]] {
  protected def asc(a1: Rep[Long]): Query[E, U, C]

  val Asc = Compiled(asc _)
}

我正在使用光滑的3.2.3

如何使scala推断正确的隐式权利?

1 个答案:

答案 0 :(得分:1)

为了使编译的宏正常工作,您需要在范围内为此宏使用隐式参数。由于特征不接受隐式参数,因此我将这些特征抽象为类。

  abstract class Fn1[A, P, E, U, C[_]](implicit ashape: Shape[ColumnsShapeLevel, A, P, A], pshape: Shape[ColumnsShapeLevel, P, P, _]) {
    protected def asc(a1: A): Query[E, U, C]
    lazy val Asc = Compiled(asc _)
  }

如果a1始终是Rep[P]

,则可以使用稍微更简单的选项。
  abstract class Fn2[P, E, U, C[_]](implicit btt: slick.ast.BaseTypedType[P]) {
    protected def asc(a1: Rep[P]): Query[E, U, C]
    lazy val Asc = Compiled(asc _)
  }

注意:如果不想使用抽象类,则可以如下定义隐式def:

trait Fn3[P, E, U, C[_]] {
  implicit def baseTypedTypeP: slick.ast.BaseTypedType[P]
  protected def asc(a1: Rep[P]): Query[E, U, C]
  lazy val Asc = Compiled(asc _)
}

实现此特征时,您应该能够按以下方式实现(如果类型已知):

implicit def baseTypedTypeP: slick.ast.BaseTypedType[Long] = implicitly