代码之家  ›  专栏  ›  技术社区  ›  Joan

列表映射无法定义类型

  •  0
  • Joan  · 技术社区  · 6 年前

    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 ?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Dmytro Mitin    6 年前

    显式指定类型参数

    val b = getValues[Parameter[Int] :: Parameter[Boolean] :: HNil, Int :: Boolean :: HNil](HList(Parameter(1), Parameter(true)))
    

    HeadParam 从隐式 hCons ( 不仅仅是 <: 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
    
    推荐文章