在函数签名中省略中间类型
Omit intermediate types in function signature
我想在无形 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)
但由于未绑定类型参数,它无法编译。
当您只想推断方法调用的某些类型参数时,正常的解决方案是将其分成 2 个:第一个修复您感兴趣的参数,returns 一个带有 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 类型推断的工作方式,它不能从 mapper1
推断 IntermediateType
然后在 mapper2
中使用它,所以我不确定它是否会正确找到 mapper2
。在未来的 Scala 版本中,这应该由 def apply(implicit mapper1: ...)(implicit mapper2: ...)
修复,但是启用此 wasn't accepted in time for 2.12.0 的拉取请求。如果这证明是个问题,您将不得不再次将 ConvertTo.apply
分成 2 个。
我想在无形 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)
但由于未绑定类型参数,它无法编译。
当您只想推断方法调用的某些类型参数时,正常的解决方案是将其分成 2 个:第一个修复您感兴趣的参数,returns 一个带有 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 类型推断的工作方式,它不能从 mapper1
推断 IntermediateType
然后在 mapper2
中使用它,所以我不确定它是否会正确找到 mapper2
。在未来的 Scala 版本中,这应该由 def apply(implicit mapper1: ...)(implicit mapper2: ...)
修复,但是启用此 wasn't accepted in time for 2.12.0 的拉取请求。如果这证明是个问题,您将不得不再次将 ConvertTo.apply
分成 2 个。