我想在无形HList上绘制两张地图,我有以下代码可以工作:
object doubleToInt extends Poly1 {
implicit def caseDouble = at[Double](_.toInt)
}
object intToDouble extends Poly1 {
implicit def caseInt = at[Int](_.toDouble)
}
def convert[InputType<:HList, ResultType<:HList, IntermediateType<:HList](input: InputType)(
implicit mapper1: Mapper.Aux[doubleToInt.type , InputType, IntermediateType],
mapper2: Mapper.Aux[intToDouble.type, IntermediateType, ResultType]
): ResultType = {
input.map(doubleToInt).map(intToDouble)
}
convert(2.5 :: HNil)
我们可以看到convert
的类型包含与此函数的调用者完全无关的类型参数IntermediateType
。以某种方式隐藏它是否可行?这是一个问题,因为我想这样打电话:
convert[SomeType, SomeType2, _](2.5 :: HNil)
但由于未绑定的类型参数,它无法编译。
答案 0 :(得分:1)
当您想要仅推断方法调用的某些类型参数时,通常的解决方案是将其拆分为2:第一个修复您感兴趣的参数并返回一个带有apply
方法的帮助器,该方法被调用以推断其余的部分。在此处应用此功能,您将获得
def convert[ResultType <: HList] = new ConvertTo[ResultType]
class ConvertTo[ResultType <: HList] {
def apply[InputType <: HList, IntermediateType <: HList](input: InputType)(implicit mapper1: Mapper.Aux[doubleToInt.type, InputType, IntermediateType],
mapper2: Mapper.Aux[intToDouble.type, IntermediateType, ResultType]
) = input.map(doubleToInt).map(intToDouble)
}
用法:convertTo[SomeType].apply(2.5 :: HNil)
。从InputType
推断input
,然后编译器找到隐式mapper1
并推断IntermediateType
。
或至少,理想情况下:由于Scala类型推断的工作方式,它无法从IntermediateType
推断出mapper1
,然后在mapper2
中使用它,所以我不确定它是否会正确找到mapper2
。在将来的Scala版本中,这应该由def apply(implicit mapper1: ...)(implicit mapper2: ...)
修复,但启用此wasn't accepted in time for 2.12.0的拉取请求。如果这是一个问题,那么您必须再次将ConvertTo.apply
拆分为2。