-
Notifications
You must be signed in to change notification settings - Fork 530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Interaction between shapeless FieldType, and Scalaz tagged types #309
Comments
I think if it works with |
This appears to be an interaction between the Scalaz encoding of tagging and shapeless's encoding of fields. With the following local definition of Scalaz tags, type Tagged[A, T] = { type Tag = T; type Self = A }
type @@[T, Tag] = Tagged[T, Tag] we get the following behaviour, val rec = 'i ->> 23.asInstanceOf[Int @@ CustomTag] :: HNil
rec('i)
[error] /home/miles/projects/shapeless/scratch/src/test/scala/shapeless/labelledgeneric.scala:416: No field Symbol with shapeless.tag.Tagged[String("i")] in record shapeless.::[Object{type Tag = shapeless.ScalazTaggedAux.CustomTag; type Self = Int} with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("i")],Object{type Tag = shapeless.ScalazTaggedAux.CustomTag; type Self = Int}],shapeless.HNil]
[error] rec('i)
[error] ^ Nevertheless, selecting for the whole field works as expected, rec.select[FieldType[Witness.`'i`.T, Int @@ CustomTag]] I'm not 100% sure what's happening here, but it seems that the two refinements (the one that encodes the shapeless field type, and the one that encodes the Scalaz tag) are interfering with inference for the relevant implicits. There is a workaround for scenarios like yours though. If you add an additional case that explicitly accommodates Scalaz tags then you get the expected results, implicit def hconsTC0[K <: Symbol, H, HT, T <: HList](implicit
key: Witness.Aux[K],
headTC: Lazy[TC[H @@ HT]],
tailTC: Lazy[TC[T]],
): TC[FieldType[K, H @@ HT] :: T] =
new TC[FieldType[K, H @@ HT] :: T] {
def apply() = s"${key.value.name}: ${headTC.value()} :: ${tailTC.value()}"
} Presumably here the additional structure in the types being resolved allows inference to succeed. Given that this works as originally written with shapeless rather than Scalaz tags, and that we have a workaround for Scalaz tags I'm going to park this for now and maybe revisit it after the 2.1.0 release. |
Thanks for the hint, didn't realize it was more general than I'd be happy to switch to shapeless' tags by the way, but I ran into #310. |
Fix for #310 about to be pushed :-) |
The workaround compiles for me without code duplication if the implementation for the tagged hcons just calls the untagged hcons. |
Is this a problem with scalaz tagged types only? I am experiencing the same issue with shapeless |
It is supposed to only be a problem with Scalaz tagged types. If you have a reproduction with shapeless tagged types would you mind posting it here? |
This is the code that is failing:
I can't derive an instance of my It is worth mentioning that the |
@Astrac something standalone would be helpful. |
This is a standalone version of the problem:
In this case the derivation fails for both |
OK, thanks. I can reproduce the problem. It's different from the one in this ticket though ... it seems to be an interaction between |
No problems, thanks! |
This is surely a Scala bug: type With[A, T] = A with T
type Struct = { def x: Int }
trait Trait { def x: Int }
class TC[T]
implicit def tc[A, T]: TC[A With T] = new TC
implicitly[TC[Trait With Serializable]] // ok
implicitly[TC[Trait with Serializable]] // ok
implicitly[TC[Struct With Serializable]] // ok
implicitly[TC[Struct with Serializable]] // nope
Information:(14, 13) tc is not a valid implicit value for TaggedTypes.TC[TaggedTypes.Struct with Serializable] because:
hasMatchingSymbol reported error: polymorphic expression cannot be instantiated to expected type;
found : [A, T]TaggedTypes.TC[TaggedTypes.With[A,T]]
(which expands to) [A, T]TaggedTypes.TC[A with T]
required: TaggedTypes.TC[TaggedTypes.Struct with Serializable]
(which expands to) TaggedTypes.TC[AnyRef{def x: Int} with Serializable]
implicitly[TC[Struct with Serializable]] // nope |
@joroKr21 interesting. Yes that does look like a scalac bug. Would you mind creating a ticket for it in scala/bug and I'll take a look. |
FTR Scalaz now uses a better encoding of tagged types based on abstract types which doesn't have this issue |
This issue is mitigated in Scalaz and at this point there is nothing more we can do here |
When using at the same time,
Lazy
, labels, and scalaz tagged types, implicits resolution withLazy
seems to fail:Full example here: https://gist.github.com/alexarchambault/ebf6ac15fceccbd37fc5#file-tc-scala
(Original reason for using scalaz
@@
was scalaz/scalaz#747, which was addressed in scalaz but not in shapeless at some point.)When using shapeless'
@@
type instead of the one of scalaz, one runs into runtime exceptions instead (I'll post an issue about it).When using
Generic
instead ofLabelledGeneric
(like in https://gist.github.com/alexarchambault/ebf6ac15fceccbd37fc5#file-tc-nonlabelled-scala), it works.The text was updated successfully, but these errors were encountered: