(长篇)插图:
// Base trait for different domains. Domains hold value-like things,
// which have some known relationships between them.
trait Domain {
type Data
type IntData <: Data
type PairData <: Data
def select(query: Query, data: Data): Data = ???
}
// Base trait for queries. Queries operate in a
// specific (but arbitrary) domain.
sealed trait Query {
def select[D <: Domain](domain: D)(data: domain.Data): domain.Data =
domain.select(this, data)
}
// Specific queries
case object IdQuery extends Query
case class SuccQuery(val q: Query) extends Query
// ...
// Specific domains
object Values extends Domain {
sealed abstract class Data
case class IntData(val data: Int) extends Data
case class PairData(val a: Data, val b: Data) extends Data
}
object Paths extends Domain {
// ...
}
object Test {
def test {
val query: Query = ???
val value: Values.Data = ???
val path: Paths.Data = ???
val valueResult = query.select(Values)(value)
val pathResult = query.select(Paths)(path)
}
}
这是一个完整的工作代码。在这个例子中,我有一个固定的结构化查询的案例层次结构,它需要以某种方式在不同的域上运行。域的公共部分是域特征的一部分。
让我们看一下Query trait中的select定义:它需要一个特定的域(应该是一个稳定的值),以及该域的依赖类型的数据。客户端将特定域和数据传递给select方法。 这是一个方法的示例,其中参数是另一个(非隐式)参数的依赖类型。
我想以某种方式“隐藏”域名,以便只传递数据(隐式传递域名)。但我不能指出它:
如果我宣布:
def select[D <: Domain](implicit domain: D)(data: domain.Data)
编译器抱怨,因为隐式方法参数应该是最后的。
如果我交换这两个参数:
def select[D <: Domain](data: domain.Data)(implicit domain: D)
编译器抱怨使用后定义域名: 非法依赖方法类型:参数出现在同一部分中的另一个参数的类型或更早的
如何隐式传递域参数?
更一般地说,是否可以使用另一个隐式方法参数的依赖类型的方法参数?
答案 0 :(得分:1)
我建议这个解决方法:
def select[D <: Domain](implicit domain: D) =
new Selector[D](domain)
class Selector[D <: Domain](domain: D) {
def data(data: domain.Data): domain.Data = ???
}
select.data(someData)