我们假设如下:
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在其他地方使用该方法是不可能的.出于多种设计原因,我试图保持这种方法的名称一致.有没有办法成功地做到这一点?
终于可以解决了。我所追求的是一种有条件附加到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。
| 归档时间: |
|
| 查看次数: |
93 次 |
| 最近记录: |