下面,我试图在Parameter
中获取HList
的所有值:
import shapeless._
case class Parameter[T](value: T)
trait ParameterOperations[Params <: HList, ParamValues <: HList] {
def values(params: Params): ParamValues
}
object ParameterOperations {
implicit val hNil = new ParameterOperations[HNil, HNil] {
override def values(params: HNil) = HNil
}
implicit def hCons[HeadParam <: Parameter[HeadParamValue], TailParams <: HList, HeadParamValue, TailParamValues <: HList](
implicit tailParamOperations: ParameterOperations[TailParams, TailParamValues]
) = new ParameterOperations[HeadParam :: TailParams, HeadParamValue :: TailParamValues] {
override def values(params: HeadParam :: TailParams): HeadParamValue :: TailParamValues =
params.head.value :: tailParamOperations.values(params.tail)
}
}
object Test extends App {
def getValues[Params <: HList, ParamValues <: HList](params: Params)(
implicit parameterOperations: ParameterOperations[Params, ParamValues]
) = parameterOperations.values(params)
val b = getValues(HList(Parameter(1), Parameter(true)))
println(b)
}
我遇到以下错误:
[error] /Users/joangoyeau/Code/autowire/autowire/jvm/src/main/scala/Test.scala:30: could not find implicit value for parameter parameterOperations: ParameterOperations[shapeless.::[Parameter[Int],shapeless.::[Parameter[Boolean],shapeless.HNil]],ParamValues]
[error] val b = getValues(HList(Parameter(1), Parameter(true)))
[error] ^
ParamValues
是否应该由隐式ParameterOperations
定义?
答案 0 :(得分:0)
要么明确指定类型参数
val b = getValues[Parameter[Int] :: Parameter[Boolean] :: HNil, Int :: Boolean :: HNil](HList(Parameter(1), Parameter(true)))
或将HeadParam
从隐式hCons
中排除(HeadParam
不只是<: Parameter[HeadParamValue]
,实际上它是是 Parameter[HeadParamValue]
)>
implicit def hCons[TailParams <: HList, HeadParamValue, TailParamValues <: HList](
implicit tailParamOperations: ParameterOperations[TailParams, TailParamValues]
) = new ParameterOperations[Parameter[HeadParamValue] :: TailParams, HeadParamValue :: TailParamValues] {
override def values(params: Parameter[HeadParamValue] :: TailParams): HeadParamValue :: TailParamValues =
params.head.value :: tailParamOperations.values(params.tail)
}
顺便说一句,您可以使用标准的ParameterOperations
和shapeless.ops.hlist.Comapped
来代替自定义类型类shapeless.ops.hlist.NatTRel
object paramToIdNatTransform extends (Parameter ~> Id) {
override def apply[T](param: Parameter[T]): T = param.value
}
def getValues[Params <: HList, ParamValues <: HList](params: Params)(implicit
comapped: Comapped.Aux[Params, Parameter, ParamValues],
natTRel: NatTRel[Params, Parameter, ParamValues, Id]
): ParamValues = natTRel.map(paramToIdNatTransform, params)
val b = getValues(HList(Parameter(1), Parameter(true)))
println(b) // 1 :: true :: HNil
实际上,它甚至更简单,shapeless.ops.hlist.Mapper
就足够了,因此您可以编写
val b = HList(Parameter(1), Parameter(true)).map(paramToIdNatTransform)
println(b) // 1 :: true :: HNil