Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何使用shapeless在编译时将类名作为字符串文本获取?_Scala_Shapeless_Scala Reflect_Singleton Type_Scala 2.13 - Fatal编程技术网

Scala 如何使用shapeless在编译时将类名作为字符串文本获取?

Scala 如何使用shapeless在编译时将类名作为字符串文本获取?,scala,shapeless,scala-reflect,singleton-type,scala-2.13,Scala,Shapeless,Scala Reflect,Singleton Type,Scala 2.13,这是以下问题的后续问题: 假设我想编写一个可以转换产品类型的递归转换器: 案例类产品( 答:Int, b:字符串 ) 但与上面的问题不同,上面的问题使用每个case类字段(a,b)作为键,我想直接使用每个类名或类型/类型构造函数名。因此,此产品类型在编译时成为记录: "Int" ->> Int "String" ->> String (可能不是一个足够好的用例,但您已经有了想法) 其中一个关键步骤是使用反射在编译时获取每个类的

这是以下问题的后续问题:

假设我想编写一个可以转换产品类型的递归转换器:

案例类产品(
答:Int,
b:字符串
)
但与上面的问题不同,上面的问题使用每个case类字段(a,b)作为键,我想直接使用每个类名或类型/类型构造函数名。因此,此产品类型在编译时成为记录:

"Int" ->> Int
"String" ->> String
(可能不是一个足够好的用例,但您已经有了想法)


其中一个关键步骤是使用反射在编译时获取每个类的名称,并将它们转换为单例类型或无形状见证。我想知道是否已经在某个地方提供了此功能?或者我真的需要一个白盒宏来实现它吗?

您必须编写一个宏

import shapeless.ops.hlist.Mapper
import shapeless.{Generic, HList, Poly1, Typeable}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox

trait FieldTypes[A <: Product] {
  type Out <: HList
}
object FieldTypes {
  type Aux[A <: Product, Out0 <: HList] = FieldTypes[A] { type Out = Out0 }

  implicit def mkFieldTypes[A <: Product, L <: HList](implicit
    generic: Generic.Aux[A, L],
    mapper: Mapper[typeablePoly.type, L]
  ): Aux[A, mapper.Out] = null

  object typeablePoly extends Poly1 {
    implicit def cse[A](implicit typeable: Typeable[A]): Case[A] = macro cseImpl[A]
    def cseImpl[A: c.WeakTypeTag](c: whitebox.Context)(typeable: c.Tree): c.Tree = {
      import c.universe._
      val str = c.eval(c.Expr[String](c.untypecheck(q"$typeable.describe")))
      val tpA = weakTypeOf[A]
      q"null.asInstanceOf[FieldTypes.typeablePoly.Case.Aux[$tpA, _root_.shapeless.labelled.FieldType[$str, $tpA]]]"
    }
  }
}

哇,好的。我将设法将您的代码合并到singleton ops中(显然已解决了所有应得的积分)。但是,让我们把它挂上几个星期,看看是否还有一件事会出现一个愚蠢友好的回答。答案可能缺少一个片段,当您将
隐式[…
分配给一个值时,它将导致编译错误:
无法找到参数e:org.shapesafe.m.FieldTypes.Aux[
@tribbloid]的隐式值好吧,如果
隐式[X]
val X=隐式[X]编译时进行编译,那就很奇怪了
不会。别忘了,
字段类型
隐式地…
必须在不同的子项目中(就像Scala 2中的宏一样)?我不能在Scastie上准备代码片段,因为它不支持多个子项目。我可以在Github上发布。是的,这很奇怪()可能是一个编译器错误。不过Bloop/BSP可以很好地编译它
import shapeless.{HNil, ::}
import shapeless.labelled.FieldType

implicitly[FieldTypes.Aux[Prod, FieldType["Int", Int] :: FieldType["String", String] :: HNil]]