As indicated in both the Type Astronaut's Guide to shapeless (footnote 4), and
Gitter April 5, 2018 3:35 PM, future versions of shapeless may change the key constraint of KeyTag
(and therefore FieldType
) from Symbol
to String
.
I am therefore trying to use string literals (supported in typelevel scala compiler, and also recent 2.12 releases with the -Yliteral-types
flag) as the key type in my fields, to future-proof my code.
However, at present, all typeclasses using labels, particularly LabelledGeneric
return FieldTypes with Symbols
as keys. For instance:
scala> import shapeless._
import shapeless._
scala> case class Foo(bar : Int)
defined class Foo
scala> LabelledGeneric[Foo]
res0: shapeless.LabelledGeneric[Foo]{type Repr = Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("bar")],Int] :: shapeless.HNil} = shapeless.LabelledGeneric$$anon$1@56635171
!!! ^^^^^^ !!!
So I'm trying to write an instance that converts LabelledGenerix.Aux.Repr
between FieldType[S <: Symbol,_]
and FieldType[S <: String,_]
, in the hope that in a future release, when the library macros/typeclasses are updated to return String
s, I will be able to simply remove that. I'm struggling to achieve this though. Essentially this boils down to implementing
def syFldToStrFld[St <: String, Sy <: Symbol, T](syFld : FieldType[Sy,T])(implicit syWit : Witness.Aux[Sy]) : FieldType[St,T] =
(syWit.value.name : String) ->> (syFld : T)
Which results in
[error] : Expression (syWit.value.name: String) does not evaluate to a constant or a stable reference value
Is there any way to work around this, at compile time? Or are there any other ways one could use String
s as keys in shapeless and have them interop with all the built-in library methods e.g. LabelledGeneric
, Record
, etc.?