总体目标:
例如,假设我想开发一个非常可插拔的问题跟踪器。它的核心实现可能只支持票证 ID 和描述。其他扩展可能会添加对各种其他字段的支持,但这些字段可能存在于同一表的数据库中。即使没有,对数据库的查询数量也不应该随着扩展数量的增加而增加。他们应该能够为查询的定义做出贡献。
Item[A, B, R[_]]
将表示一列,A
表类型(具有列表示)B
作为数据类型,并R
作为表示类型列的类型构造函数B
。例如,ScalaQueryR[B]
可能也是如此。NamedColumn[String]
现在我正在尝试创建一个类型类来处理构建“查询”。
问题:
以 val q 开头的行(在末尾)应该读起来很简单val q = query(items)
并且仍然可以编译。defaultNext
由于推断B0
和/或B
to ,各种尝试产生推断类型参数不符合预期类型参数Nothing
的错误,或“发散隐式扩展”错误或其他错误。我认为隐式错误是由不正确的类型推断触发的。
我已经在这上面浪费了好几天(这是我的一个开源项目),所以如果有人能帮忙,我真的很感激。
class CanBuildQuery[A, B, R[_], Q, I <: Item[A, B, R]](val apply: I => A => Q)
trait Low {
implicit def defaultNext[A, B, R[_], B0, P <: Item[A, B0, R], I <: NextItem[A, B, B0, R, P], PQ](
implicit cbq: CanBuildQuery[A, B0, R, PQ, P]
): CanBuildQuery[A, B, R, (PQ, R[B]), I] =
new CanBuildQuery[A, B, R, (PQ, R[B]), I](sys.error("todo"))
}
object CanBuildQuery extends Low {
implicit def defaultFirst[A, B, R[_]]:
CanBuildQuery[A, B, R, R[B], FirstItem[A, B, R]] =
new CanBuildQuery[A, B, R, R[B], FirstItem[A, B, R]](_.get)
}
def query[A, B, R[_], Q, I <: Item[A, B, R]](
i: I with Item[A, B, R]
)(
implicit cbq: CanBuildQuery[A, B, R, Q, I]
): A => Q =
cbq apply i
trait Item[A, B, +R[_]] {
def get: A => R[B]
}
trait FirstItem[A, B, +R[_]] extends Item[A, B, R] {
def get: A => R[B]
}
trait NextItem[A, B, B0, +R[_], I <: Item[A, B0, R]] extends Item[A, B, R] {
val prev: I
def get: A => R[B]
}
val items =
new NextItem[Boolean, String, Long, Option, FirstItem[Boolean, Long, Option]]{
val get = { _:Boolean => "hello" }
val prev = new FirstItem[Boolean, Long, Option] {
val get = { _:Boolean => 73 }
}
}
val q = query(items)(CanBuildQuery.defaultNext(CanBuildQuery.defaultFirst))