Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
745 views
in Technique[技术] by (71.8m points)

shapeless - In scala 2.13, why sometimes TypeTags cannot be inferred? And how to construct one from a variable symbol?

Here is a simple example in shapeless:

  it("from Witness") {

    val ttg = implicitly[TypeTag[Witness.Lt[String]]]
    val ctg = implicitly[ClassTag[Witness.Lt[String]]]
  }

  it("... from macro") {

    val ttg = implicitly[TypeTag[Witness.`1`.T]]
    val ctg = implicitly[ClassTag[Witness.`1`.T]]
  }

  it("... doesn't work") {

    val ttg = implicitly[TypeTag[w1.T]] // failed!
    val ctg = implicitly[ClassTag[w2.T]]
  }

The second and third it block have very similar bytecode (after the Witness.? macro has been invoked), yet one succeed and one failed:


[Error] /home/peng/git-spike/scalaspike/common/src/test/scala/com/tribbloids/spike/scala_spike/Reflection/InferTypeTag.scala:55: No TypeTag available for com.tribbloids.spike.scala_spike.Reflection.InferTypeTag.w1.T

What could have caused this? And how do I circumvent this problem?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you switch on scalacOptions += "-Xlog-implicits" you'll see

val w1 = Witness(1)
val ttg = implicitly[TypeTag[w1.T]] // doesn't compile

//materializing requested reflect.runtime.universe.type.TypeTag[App.w1.T] using scala.reflect.api.`package`.materializeTypeTag[App.w1.T](scala.reflect.runtime.`package`.universe)

//scala.reflect.api.`package`.materializeTypeTag[App.w1.T](scala.reflect.runtime.`package`.universe) is not a valid implicit value for reflect.runtime.universe.TypeTag[App.w1.T] because:
//failed to typecheck the materialized tag: 
//cannot create a TypeTag referring to type shapeless.Witness.<refinement>.T local to the reifee: use WeakTypeTag instead

//No TypeTag available for App.w1.T

So try to use WeakTypeTag as recommended

val w1 = Witness(1)
val ttg2 = implicitly[WeakTypeTag[w1.T]] // compiles

In Scala, why it is impossible to infer TypeTag from type alias or dependent type?

Why there is no TypeTag available in nested instantiations (when interpreted by scala code runner)?

Typetags not working inside of code block scope?

Type aliases screw up type tags?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...