抱歉标题太糟糕了,不确定有没有更好的。这是我的问题的粗略简化(对不起,如果它看起来微不足道,毫无意义):
class RList[T](data: List[T]) {
def map[V](f: T=>V): RList[V] = ...
}
一个
RList
的想法(Restricted List) 就是你不能调整它的大小,也不能改变其中元素的顺序。但是您可以使用为您提供一个包含更改数据的新 RList 的函数。现在需要有一个函数来创建 RLists。它可能有一个类似的签名:
def toRList[T](values: List[T]): RList[T] = ...
到现在为止还挺好。但现在是棘手的部分。我需要一个像这样工作的函数:
def zip[T, V](left: RList[T], right: RList[V]): RList[(T,V)]
但是附加的约束是
left
和 right
有相同的起源。因此,它们可以保证大小相同。例如应该编译的代码:
val x = toRList(List(1, 2, 3))
val y = x.map(_ * 2)
val z = y.map(_.toString)
zip(y,z)
例如应该无法编译的代码
val y = toRList(List(2, 4, 6))
val z = toRList(List("one", "two"))
zip(y,z)
*注意:在我原来的问题中,对 zip 的约束需要是它们来自同一个“来源”。仅仅保证它们的长度是不够的(更不用说,在编译时不知道列表的大小)*
我还需要能够使用
zip
多次,所以应该编译这样的东西zip(a,zip(b,c))
(假设
a
、 b
和 c
来自同一来源)谢谢!
最佳答案
这对你有用吗?
object PathDependentTypes {
trait RListProducer {
trait RList[T] {
def map[V](f: T => V): RList[V]
def zip[V](r: RList[V]) : RList[(T, V)]
}
def getList[T]: RList[T] = ???
}
class A extends RListProducer
def main(args: Array[String]) {
val aSource = new A
val a = aSource.getList[Int]
val anotherSource = new A
val b = anotherSource.getList[String]
val m1 = a.map( _ * 2)
val m2 = a.map( _.toString)
val z1 = m1.zip(m2)
//val z2 = a.zip(b) //doesn't compile because A and B aren't the same.
val z3 : A#RList[(Int, (Int, String))] = a zip (m1 zip m2)
}
}
关于scala - 基于原点的约束函数(路径依赖类型?类型生成?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12025604/