使用更高的kinded类型访问上下文边界的类型构造函数参数

时间:2012-12-06 13:29:33

标签: scala higher-kinded-types context-bound

是否可以在上下文绑定中访问高级类型的类型构造函数参数?我期待定义一个采用更高kinded类型的特征,并有一个返回构造函数参数实例的方法。

case class A[TContents](c: TContents) {
  def foo = c
}

case class B[TContents](c: TContents) {
  def foo = c
}

trait Fooable[TClass[_ <: TContents], TContents] {
  def foo(obj: TClass[TContents]): TContents
}

case class AFooable[TContents] extends Fooable[A, TContents] {
  def foo(obj: A[TContents]) = obj.foo
}

case class BFooable[TContents] extends Fooable[B, TContents] {
  def foo(obj: B[TContents]) = obj.foo
}

class test {
  def getFoo[TType[_] : Fooable, TContents](obj: TType[TContents]): TContents = 
    implicitly[Fooable[TType, TContents]].foo(obj)

  implicit def aFooable = AFooable

  val a = A(1)
  val foo = getFoo(a)
}

这失败了,编译器错误抱怨上下文边界不能有两个类型参数,但我找不到另一种方法来访问类型构造函数参数?

1 个答案:

答案 0 :(得分:3)

您有两种选择 - 使用type lambda trick部分应用Fooable(呃):

def getFoo[TType[_]: ({type L[A[_]] = Fooable[A, TContents]})#L, TContents](
  obj: TType[TContents]
): TContents = implicitly[Fooable[TType, TContents]].foo(obj)

或者去除上下文的限制(在我看来更好):

def getFoo[TType[_], TContents](obj: TType[TContents])(
  implicit ev: Fooable[TType, TContents]
): TContents = ev.foo(obj)

请注意,在任何一种情况下,您都需要为aFooable提供类型参数:

implicit def aFooable[A] = AFooable[A]

我强烈建议遵守有关无参数列表的案例类的警告。