如何在Scala 3中实现无asInstanceOf的tupled谓词组合函数?
在Scala 3中实现类型安全的元组谓词组合函数
需求说明
需要实现一个tupled函数,接收与参数元组类型对应的谓词元组,将每个谓词应用到对应参数上,并用&&组合所有结果,要求不使用asInstanceOf或isInstanceOf,允许使用inline、宏等Scala 3特性。
函数定义如下:
type Pred[A] = A => Boolean /** 计算谓词的值并使用`&&`组合结果。 * * 实现不使用`asInstanceOf`或`isInstanceOf` */ inline def tupled[Args <: Tuple](inline preds: Tuple.Map[Args,Pred], inline args: Args): Boolean
实现方案
利用Scala 3的inline元组模式匹配特性,在编译期递归处理元组元素,完全避免类型转换:
type Pred[A] = A => Boolean inline def tupled[Args <: Tuple](inline preds: Tuple.Map[Args, Pred], inline args: Args): Boolean = inline (preds, args) match // 空元组返回true(逻辑与的单位元) case (EmptyTuple, EmptyTuple) => true // 递归处理非空元组:应用第一个谓词到对应参数,再组合剩余结果 case (p *: ps, a *: as) => p(a) && tupled(ps, as)
代码解释
- 编译期展开:
inline关键字让编译器在编译阶段将元组的模式匹配展开为逐个元素的处理逻辑,无运行时开销 - 类型安全保证:
Tuple.Map[Args, Pred]确保谓词元组的每个元素类型与参数元组对应位置的类型严格匹配,编译器会在调用时拦截类型不匹配的错误 - 递归终止条件:空元组返回
true,符合逻辑与运算的单位元特性(没有谓词需要验证时结果为真)
示例验证
运行以下测试代码,结果符合预期:
val pred: (Int => Boolean, Int => Boolean) = (_ < 0, _ > 0) println(tupled[(Int, Int)](pred)(1, 2)) // 输出 false println(tupled[(Int, Int)](pred)(-1, 2)) // 输出 true
内容的提问来源于stack exchange,提问作者Koosha
相关产品推荐
相关产品推荐

