使用依赖类型生成编译错误

时间:2014-11-24 16:27:37

标签: scala shapeless

用例:编写像

这样的通用函数
def tenantFilterQuery[T, Q <: Table[T]](t: Q, e: TableQuery[Q], id: Int)(implicit s: Session) :Query[Q,Q#TableElementType,Seq] = {
  e.filter(_.tenantId === id)
}

我正在尝试添加编译时智能,e.filter(_.tenantId === id)过滤器应仅适用于传递T存在名为tenantId的属性,否则它将不会应用该过滤器{} {1}}没有那个属性。

可以使用或不使用无形的相关路径类型来解决这个问题吗?

第二步尝试提出一种方法,即在最终T生成时Query具有名为T的属性,如果它没有,它将在编译时失败'在tenantId上有filter。想想我应该在第一个被弄清楚的时候为这个问题创建一个单独的问题。

1 个答案:

答案 0 :(得分:0)

第二个问题是更简单的问题:您可以使用结构类型T <: {def tenantId: Int},然后只能使用T来调用它。

如果您希望过滤器针对这些类型发生而不是针对其他类型发生,我想您可以通过提供隐式帮助器来实现此目的吗?类似的东西:

sealed trait Helper[T]{
  def applyToQuery[Q <: Table[T]](e: TableQuery[Q]): TableQuery[Q]
} 
trait LowPriorityHelper {
  implicit def withoutTenantId[T] = new Helper[T] {
    def applyToQuery[Q <: Table[T]](e: TableQuery[Q]): TableQuery[Q] = e
  }
}
object Helper extends LowPriorityHelper {
  implicit def withTenantId[T <: {def tenantId: Int}] =
    new Helper[T] {
      def applyToQuery[Q <: Table[T]](e: TableQuery[Q]): TableQuery[Q] =
        e.filter(_.tenantId === id)
    }
}

def doQuery[T: Helper] = { val e = ...; implicitly[Helper[T]].applyToQuery(e)...}

withTenantId Helper将传递给T的{​​{1}},否则传递tenantId