【问题标题】:Method parameter of dependent type of another implicit method parameter - is it possible?另一个隐式方法参数的依赖类型的方法参数 - 可能吗?
【发布时间】:2014-05-04 20:06:55
【问题描述】:

(略长的)插图:

// 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 方法。 这是一个方法示例,其中一个参数是另一个(非隐式)参数的依赖类型。

我想以某种方式“隐藏”域,以便只传递数据(隐式传递域)。但我不能完全确定:

  1. 如果我声明:

    def select[D <: Domain](implicit domain: D)(data: domain.Data)
    

    编译器抱怨,因为隐式方法参数应该排在最后。

  2. 如果我交换两个参数:

    def select[D <: Domain](data: domain.Data)(implicit domain: D)
    

    编译器抱怨域在使用后被定义: 非法的依赖方法类型:参数出现在同一节或更早的另一个参数的类型中

如何使域参数隐式传递?

更一般地说,是否可以有另一个隐式方法参数的依赖类型的方法参数?

【问题讨论】:

  • 你为什么不干点类似def select(data: Domain#Data) = { val domain = data.domain; ... }的事情?

标签: scala


【解决方案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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 2015-03-01
    • 2012-10-09
    • 2022-11-13
    • 1970-01-01
    • 2019-09-09
    相关资源
    最近更新 更多