为何Scala报found bH.type required B类型错误,该如何修复?
Scala 编译错误定位与修复
报错根因
你遇到的found : bH.type (with underlying type B) [error] required: B类型不匹配报错,核心是内部尾递归辅助函数的泛型参数重复定义遮蔽问题:
- 外层方法
znajdz已经定义了整套泛型参数A、B,同时声明了对应类型的谓词参数pred,但内部定义assist时,重复声明了同名的独立泛型<A,B>,导致辅助函数和外层方法的泛型完全割裂开,形成了两套互不关联的类型体系。 - 类型推断逻辑随之出现偏差:当在
assist内部调用外层的pred方法时,编译器为了匹配pred固定的入参类型要求,会把模式匹配拿到的首元素aH、bH的单例类型,强行绑定为assist自身泛型的实际取值,最终出现类型不匹配——即编译器识别到传入的是单例类型bH.type,但辅助函数的递归参数要求的是通用的B类型。 - 这种重复泛型声明本身也不符合尾递归辅助函数的设计逻辑:辅助函数完全可以直接复用外层的泛型上下文,不需要重新定义一套独立的泛型参数。
修复方案
去掉内部assist函数的独立泛型声明,直接复用外层znajdz的A、B泛型上下文即可,修复后的完整代码如下:
object Zad1 { type Pred[T] = T => Boolean def main(args: Array[String]): Unit = { } def znajdz[A,B](alist: List[A], blist: List[B])(pred: Pred[(A,B)]): Set[(A,B)] = { @annotation.tailrec // 移除了重复的<A,B>泛型声明,直接复用外层方法的泛型上下文 def assist(alist: List[A], blist: List[B], tail: Set[(A,B)]): Set[(A,B)] = { (alist, blist) match { case (aH :: aT, bH :: bT) => if (pred((aH, bH))) assist(aT, bT, Set((aH, bH)) ++ tail) else assist(aT, bT, tail) case _ => tail } } assist(alist, blist, Set.empty) } }
注:原代码中嵌套
match判断谓词返回值的逻辑,简化为普通if判断不改变原有功能,同时能减少不必要的模式匹配开销。
内容的提问来源于stack exchange,提问作者Fabulouseq
相关产品推荐
相关产品推荐

