Constrain function based on origin (Path Dependent type? Type Generation?)

Viewed 193

Sorry about terrible title, not sure of a better one. Here's a gross simplification of my problem (Sorry if it seems so trivial, that it's pointless):

class RList[T](data: List[T]) {
   def map[V](f: T=>V): RList[V] = ...
}

The idea of an RList (Restricted List) is that you can't resize it, or change the order of the elements in it. But you can use functions that give you a new RList with changed data in it.

Now there needs to be a function that creates RLists. It might have a signature something like:

def toRList[T](values: List[T]): RList[T] = ...

So far, so good. But now the tricky part. I need a function that works like this:

def zip[T, V](left: RList[T], right: RList[V]): RList[(T,V)]

But with the additional constraint that left and right have the same origin. Thus, they are guaranteed to be the same size.

e.g. Code that should compile:

val x = toRList(List(1, 2, 3))
val y = x.map(_ * 2)
val z = y.map(_.toString)
zip(y,z)

e.g. Code that should fail to compile

val y = toRList(List(2, 4, 6))
val z = toRList(List("one", "two"))
zip(y,z)

*Note: In my original problem the constraint on zip needs to be that they are from the same 'source'. Merely guaranteeing they are the same length isn't good enough (Not to mention, the size of the list isn't known at compile time) *

I also need to be able to use zip multiple times, so something like this should compile

zip(a,zip(b,c))

(assuming a, b and c are from the same source)

Thanks!

2 Answers
Related