estatico / scala-newtype

NewTypes for Scala with no runtime overhead
Apache License 2.0
540 stars 31 forks source link

No TypeTag available for newtypes #58

Open LMnet opened 4 years ago

LMnet commented 4 years ago

Currently, there is no way to get a TypeTag for a newtype:

@newtype case class WidgetId(toInt: Int)

val widgetId = WidgetId(5)

import scala.reflect.runtime.universe._

val tt = typeTag[WidgetId] // failed with No TypeTag available

WeakTypeTag works fine:

val wtt = weakTypeTag[WidgetId]

Also, I can get a TypeTag for the Repr type:

val repr = typeTag[WidgetId.Repr]

Looks like there is no way to get a TypeTag for the newtype in the current newtype encoding because newtype's type is abstract, but TypeTag can be summoned only for a concrete type.

About my use case: I'm using doobie and it uses TypeTags very extensively for better logging and error reporting.

carymrobbins commented 4 years ago

It seems one workaround would be to use Coercible (special thanks to @hmemcpy for pointing this out to others)

implicit def coercibleMeta[R, N](implicit ev: Coercible[Meta[R], Meta[N]], R: Meta[R]): Meta[N] = ev(R)

https://twitter.com/hmemcpy/status/1253731339825790976?s=19

hmemcpy commented 4 years ago

Yeah, unfortunately I couldn't get the tmap/tcontramap variant working, so this workaround uses the regular map/contramap on doobie types. This works, but as @LMnet mentions, won't provide decent logging output when things go wrong.