In scala, How to call generalised copy function of a case class if it is declared in a family outer type?

74 Views Asked by At

This is a scala problem caused by path-dependent type: Considering that I have a family type:

trait Outer {
  
  case class Inner(v: Int) {

    val outer = Outer.this
  }
}

If I want to call Outer#Inner.copy() when the instance of Outer is unknown:

def cp(src: Outer#Inner) = {
  src.copy()
}

I will run into a compilation error. as the type signature of src.copy() is attached to its outer instance.

One way to bypass this is to extract the outer instance manually:

def cp(src: Outer#Inner) = {
  val o = src.outer
  val _src = src.asInstanceOf[o.Inner]

  _src.copy()
}

This can compiler successfully, but the asInstanceOf[] is clearly a hacking artefact and should be removed.

In idiomatic scala, what's the best way to achieve the same goal, while let the scala compiler automatically infer the existence of outer, and generate the correct type signature without blind type casting?

1

There are 1 best solutions below

5
username On

Instead of Outer#Inner, you need to constrain the Outer type using a type parameter. Try

def cp[O <: Outer](src: O#Inner): O#Inner = src.copy()

This will let you maintain O#Inner, which refers to one specific type, as opposed to Outer#Inner.

See it in Scastie.