具有路径依赖/嵌套类型的Scala类型擦除问题

fla*_*ian 5 scala

我们假设如下:

class Wrapper1 {
  case class Condition(test: String)
}
object Wrapper1 extends Wrapper1

class Wrapper2 {
  case class Condition[A](test: String)
}
object Wrapper2 extends Wrapper2


class Test 
  type T = // whatever

  def test(fn: T => Wrapper1.Condition): X
  def test[R](fn: T => Wrapper2.Condition[R]): X
}
Run Code Online (Sandbox Code Playgroud)

问题是由于类型擦除,这些方法在擦除后具有完全相同的类型.可以很容易地改变第二个的签名:

def test[R](fn: T => Wrapper2.Condition[R])(implicit ev: R =:= R): X
Run Code Online (Sandbox Code Playgroud)

但这会混淆编译器并test在其他地方使用该方法是不可能的.出于多种设计原因,我试图保持这种方法的名称一致.有没有办法成功地做到这一点?

fla*_*ian 0

终于可以解决了。我所追求的是一种有条件附加到HList. 基本上同一方法的多个重载必须共存,因为它们会返回不同类型的HList.

为了只有一种方法,需要参数来指示该方法的最终签名是什么样的。

因此,我们假设以下情况,该test方法必须返回

def test[RR](arg: Type1[RR]): Wrapper[RR :: ExistingHList]
Run Code Online (Sandbox Code Playgroud)

或者分别:

def test(arg: Type2): Wrapper[ExistingList]
Run Code Online (Sandbox Code Playgroud)

同样的方法必须附加到一个Hlist取决于参数是否满足某些条件。该修复与 using 一样简单,如果我们尝试附加到 hlist,shapeless.ops.hlist.Prepend它将默认返回现有的。HListHNil

Type2将return的参数HNil隐式转换为最终会成为的东西HNil是有效的方法。

具体来说:

  class Wrapper[PS <: HList] {
    def test[
      RR,
      HL <: HList,
      Out <: HList
    ](
      condition: T => Wrapper[HL]
    )(implicit prepend: Prepend.Aux[HL, PS, Out]): Wrapper[Out[
  }
Run Code Online (Sandbox Code Playgroud)

如果条件函数将在Wrapper[HNil]函数不需要修改最终返回类型的情况下返回 a,则此方法有效。修改的函数可以自由地独立构建自己的函数HList