Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Scala, how can I restrict multiple parameters must be a type inside the same type?

I'm trying to use path dependent type with generics.

I have two classes, the class C2 is nested in C1.

case class C1(v1: Int) {
  case class C2(v2: Int)
}

And I have two object of class C1 here:

object O1 extends C1(1)
object O2 extends C1(2)

I want to write a method that accept multiple parameters of type C2. And all of these parameters must belongs to the same object of C1.

For example:

foo(O1.C2(10), O1.C2(11)) // all the C2 is inside the same O1
foo(O1.C2(10), O2.C2(20)) // not good, will not compile

I have tried some ways to write this kind of method, but no one works.

The first one:

def print1(p1: C1#C2, p2: C1#C2): Unit = {
  println(p1.v2, p2.v2)
}
print1(O1.C2(1111), O2.C2(2222)) // Not requited that p1 & p2 should have the same object of C1

The second one:

def print2(p1: O1.C2, p2: O1.C2): Unit = {
  println(p1.v2, p2.v2)
}
print2(O1.C2(1111), O1.C2(1111)) // Can only accept the C2 inside O1

The third one:

def print3[T <: C1#C2](p1: T, p2: T): Unit = {
  println(p1.v2, p2.v2)
}
print3(O1.C2(1111), O2.C2(2222)) // The same as the first one.

The last one:

//  def print2[U <: C1](p1: U.C2, p2: U.C2): Unit = {
//    println(p1.v2, p2.v2)
//  }
// Not compile, Error: not found: value U

Is there anyway that I can archive this?

like image 915
lxohi Avatar asked Mar 11 '23 08:03

lxohi


1 Answers

You can do it, but you need to pass the object itself as well:

def print(o: C1)(p1: o.C2, p2: o.C2) = ...

print(O1)(O1.C2(1111), O2.C2(2222))
like image 114
Alexey Romanov Avatar answered Mar 13 '23 05:03

Alexey Romanov