问题描述
在针对我的项目编译单个小型测试文件时,我遇到了非常难以预测的编译器行为。它测试使用递归类型参数化的见证类的隐式值的存在。对类型参数的微小更改会产生不同的结果,OutOfMemoryError
,StackOverflowError
,一秒钟内编译,半小时内编译,无限期挂起(scalac不会在一整夜内退出),不编译(我不会说“尽管应该”,但肯定可以做到-隐式声明可以组成一棵树,该树具有正确的类型参数,与搜索到的隐式值匹配)。 / p>
隐式定义本身并不多,并且以 linear 的方式递归:对于任何输入类型,最多可以将一个定义与结果统一,该接受一个类型实参的隐式见证输入类型的考虑一个HList
,但具有不同的“链接”子类型,并搜索满足特定条件的输入HList
类型的前缀。我怀疑该问题来自三个因素:
- 隐式类型在其“输入”类型参数中是互变的,这意味着有时会为实际输入类型的超类型声明正确的定义。
- 在解析过程中发生的某些类型(“输入”类型)是上限(以
L[H,T] forSome { type L[H,T <: HList] <: H::T }
为界的抽象类型)。 - 隐式声明本身包含许多类型参数,因为隐式类型具有多个类型参数和更多类型成员,并且需要为其寻找隐式的“输入类型”需要分解为类型构造函数,其类型参数,这些类型参数的范围。
我所做的一个发现使我走得更远,并得出了上述假设:发现是从泛型声明中替换非递归支持隐式声明(该声明要求编译器执行类型统一和分解更高类型的声明。到其类型构造函数和类型参数中),并为每个“链接”类型分别提供了简单明了的定义,从而分别为某些输入类型加快了速度。更改仅出于说明目的,因为原始文档具有很多项目内依赖项,如下所示:
implicit def composition[L <: FromSome,R[O] <: Elem[O],J[+A <: FromSome,B[O] <: Elem[O]] <:
(A Link B) { type LikeLink[+X <: FromSome,Y[O] <: Elem[O]] <: X J Y }]
:LinkComposition[L,R,J] = ???
进入
implicit def compositionA[L <: FromSome,R[O] <: Elem[O]] :LinkComposition[L,LinkA] = ???
implicit def compositionB[L <: FromSome,LinkB] = ???
...
其中
trait LinkComposition[L <: FromSome,B[O] <: R[O]] <: A Link B]
extends Decomposition[L J R,L,FromSome]
trait Decomposition[-Whole,Part <: Bound,Bound]
Decomposition
是Whole
的类型类,供使用FromSome
/ Link
类型的隐式定义使用,以将类型参数减少为其前缀({ {1}}和Part
是“输出”类型,因为编译器本身无法实例化Bound
的类型参数[F <: Link[L,R],L <: FromSome,R[O] <: Elem[O]]
。
这项更改使某些情况下可以在大约半小时内编译或立即用尽内存的情况立即编译,但是更复杂的类型仍然无法工作。
因此,我想知道:用于实例化泛型方法的类型参数的算法是否本质上是幂生的,我是否可以了解更多信息或以某种方式进行调试?因为我正处于通过盲目,随机变化,猜测和祈祷并没有取得太大进展来解决这个问题的第三天。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)