本文介绍了类型参数声明中的无形解构元组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用RightFolder,它返回一个Tuple2,并想返回_1部分.第一个版本rightFoldUntupled1可以正常工作,但使用其他的IsComposite类型类.

I am using a RightFolder that returns a Tuple2 and would like to return the _1 part. The first version rightFoldUntupled1 works fine but uses an additional IsComposite typeclass.

在第二个版本rightFoldUntupled2中,我尝试通过将P分解为Product2[_, Values]而在没有IsComposite的情况下实现相同的目的.这不再起作用-编译器很高兴看到P是Product2[_,_],但是一旦我对_1使用命名类型参数,它就不再编译.知道为什么吗?

In the second version rightFoldUntupled2 I try to achieve the same without IsComposite by destructuring P as a Product2[_, Values]. That doesn't work any more - the compiler is happy to witness that P is a Product2[_,_], but as soon as I use a named type parameter for _1 it doesn't compile any more. Any idea why?

完整的源代码(准备使用隐式调试输出运行sbt)在这里: https://github.com/mpollmeier/shapeless-playground/tree/f3cf049

The full source (with sbt ready to ~run with implicit debug output) is here: https://github.com/mpollmeier/shapeless-playground/tree/f3cf049

case class Label[A](name: String)

val label1 = Label[Int]("a")
val labels = label1 :: HNil

object getValue extends Poly2 {
  implicit def atLabel[A, B <: HList] = at[Label[A], (B, Map[String, Any])] {
    case (label, (acc, values)) ⇒
      (values(label.name).asInstanceOf[A] :: acc, values)
  }
}

// compiles fine
val untupled1: Int :: HNil = rightFoldUntupled1(labels)

// [error] could not find implicit value for parameter folder:
// shapeless.ops.hlist.RightFolder.Aux[shapeless.::[Main.DestructureTupleTest.Label[Int],shapeless.HNil],
//(shapeless.HNil, Map[String,Any]),Main.DestructureTupleTest.getValue.type,P]
val untupled2: Int :: HNil = rightFoldUntupled2(labels)

def rightFoldUntupled1[L <: HList, P <: Product2[_, _], Values <: HList](labels: L)(
  implicit folder: RightFolder.Aux[L, (HNil, Map[String, Any]), getValue.type, P],
  ic: IsComposite.Aux[P, Values, _]
): Values = {
  val state = Map("a" -> 5, "b" -> "five")
  val resultTuple = labels.foldRight((HNil: HNil, state))(getValue)
  ic.head(resultTuple)
}

def rightFoldUntupled2[L <: HList, Values, P <: Product2[_, Values]](labels: L)(
  implicit folder: RightFolder.Aux[L, (HNil, Map[String, Any]), getValue.type, P]
): Values = {
  val state = Map("a" -> 5, "b" -> "five")
  val resultTuple = labels.foldRight((HNil: HNil, state))(getValue)
  resultTuple._1
}

推荐答案

此方法应与rightFoldUntupled1相同:

def rightFoldUntupled2[L <: HList, Values, M](labels: L)(
  implicit folder: RightFolder.Aux[L, (HNil, Map[String, Any]), getValue.type, (Values, M)]
  ): Values = {
  val state = Map("a" -> 5, "b" -> "five")
  val resultTuple = labels.foldRight((HNil: HNil, state))(getValue)
  resultTuple._1
}

这篇关于类型参数声明中的无形解构元组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 19:36