【发布时间】:2012-07-10 06:53:09
【问题描述】:
总体目标:
例如,假设我想开发一个非常可插拔的问题跟踪器。它的核心实现可能只支持票证 ID 和描述。其他扩展可能会添加对各种其他字段的支持,但这些字段可能存在于同一表的数据库中。即使没有,对数据库的查询数量也不应该随着扩展数量的增加而增加。他们应该能够为查询的定义做出贡献。
Item[A, B, R[_]] 表示一列,A 表示表类型(具有列表示形式),B 作为数据类型,R 作为类型构造函数,表示类型为 B 的列.所以R[B] 可能是 ScalaQuery 的NamedColumn[String],例如。
现在我正在尝试创建一个类型类来处理构建“查询”。
问题:
以 val q 开头的行(在末尾)应该简单地阅读 val q = query(items) 并且仍然可以编译。由于defaultNext 将B0 和/或B 推断为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))
【问题讨论】:
-
你真的希望有人阅读和分析这一切吗?你必须缩小范围。请尊重读者的时间
-
顺便说一句,我认为 SO 帮助应该是针对特定问题,而不是像“我不能自己开发系统的这一部分,所以我请其他人来构建它”。
-
我认为反对票完全没有。很可能,它们来自对问题不了解的人,只是看着一堆代码并认为“哎呀,这很难!”。问题已明确说明,虽然我更喜欢较低的 LoC,但我碰巧知道这已经是较低的 LoC。
-
由于括号、方括号和函数中的参数数量,代码无法编译。你能解决这些问题以帮助处理如此大量的代码吗?
-
@ChrisJamesC - 看起来其他人编辑了代码并且不小心遗漏了一个]。我修好了。