我想利用这个模式:
def accept[T](a: RList[T]) = true
def accept[T, V](a: RList[T], b: RList[V])(implicit ev: a.S =:= b.S) = true
def accept[T, V, Q](a: RList[T], b: RList[V], c: RList[Q])(implicit ev: a.S =:= b.S, ev2: b.S =:= c.S) = true
但有它接受KList
,而不是手动覆盖所有arities。 基本上我想说的,“采取任何数量的RList
的时候,那些具有相同的S
成员类型”
RList
是一个特点,即包含一个类型S
。 (有关的RLIST,为什么我这样做更多的背景,请参阅: 约束功能基于出身(路径依赖型发电类型)? )
它看起来像你在做什么,只是试图让编译器检查类型的同意,因为你的方法总是返回true。
你能也许,反而让这些接受它们的任意数的方法,接受这是保证有S中的所有匹配“RLists的名单”?
下面是这样一个名单可能会构成:
package rl {
// A simplified version of your RList:
trait RList[T] {
type S
def data: List[T]
}
// A list of RLists which have identical S
sealed trait RListList
// RListNil is an empty list
trait RListNil extends RListList {
def ::[H <: RList[_]](h: H) = rl.::[h.S,H,RListNil](h, this)
}
// there is exactly one RListNil
case object RListNil extends RListNil
// List can be a cons cell of lists sharing the same S
final case class ::[S, H <: RList[_], T <: RListList](head: H, tail: T) extends RListList {
// We only allow you to cons another to this if we can find evidence that the S matches
def ::[H2 <: RList[_]](h: H2)(implicit ev: =:=[h.S,S]) = rl.::[S,H2,::[S,H,T]](h, this)
}
现在,如果我们试图建立不具有所有S类型同意一个RListList,编译器会赶上我们:
object RListTest {
val list1 = new RList[Int] { type S = String; def data = List(1,2,3,4) }
val list2 = new RList[String] { type S = String; def data = List("1","2","3","4") }
val list3 = new RList[Double] { type S = Float; def data = List(1.1,2.2,3.3,4.4) }
val listOfLists1 = list1 :: RListNil // fine
val listOfLists2 = list2 :: listOfLists1 // still fine, since list1 and list2 have the same S
val listOfLists3 = list3 :: listOfLists2 // compiler error: Cannot prove that java.lang.String =:= Float
}
这是使用从属方法类型,这意味着需要使用阶2.10或需要与-Ydependent-方法类型来编译2.9.x切换