You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In order to migrate all modules that use EnumType[] to scala3 (e.g. bigquery, avro) one aspect should be implemented in scala3 that is in place in scala2 implementation.
How Magnolia work with implicits in scala2
If compiler detects the same type of implicits imported from two scopes it fails with "could not find implicit value for parameter" error:
implicitly[Typeclass[SomeType]].act(...
/ \
/ \
[ import X._ ] [ import Y._ ]
/ \
/ \
object X { object Y {
implicit def imp1[T]: Typeclass[T] implicit def imp2[T]: Typeclass[T]
[ compilation error ]
could not find implicit value for parameter x: Typeclass[
If one of those imported instances requires another type class implicitly then compiler still fails treating both implicits with an equal priority:
implicitly[Typeclass[SomeType]].act(...
/ \
/ \
[ import X._ ] [ import Y._ ]
/ \
/ \
object X { object Y {
implicit def imp1[T]: Typeclass[T] implicit def imp2[T: AnotherTypeClass]: Typeclass[T]
[ compilation error ]
could not find implicit value for parameter x: Typeclass[
Even if implicit for AnotherTypeClass is not fulfilled, or even if it provided by native macro that aborts in such case:
That depends on AnotherTypeClass in the definition of def join[T: AnotherTypeClass]
But if the first implicit is defined with Magnolia macro as well then it is supposed to work like this:
imp2 is aborted in genMacro by some condition for T so imp1 is chosen
if T is product with fields of other types like Q, for that type imp2 is chosen
AnotherTypeClass is used to differentiate types and turn ON or OFF a macro.
Apparently this is how macros are generated to Java. Decompiled Java sources might be checked to see why and how exactly Magnolia is switching between implicits, because Scala itself doesn't provide this way.
How Magnolia work with implicits in scala3
If compiler detects the same type of implicits imported from two scopes it fails with "Ambiguous given instances" error:
summon[Typeclass[SomeType]].act(...
/ \
/ \
[ import X.given ] [ import Y.given ]
/ \
/ \
object X { object Y {
given imp1[T]: Typeclass[T] given imp2[T]: Typeclass[T]
[ compilation error ]
Ambiguous given instances: both given instance imp1 in object X and given instance imp2 in object Y match type...
If one of those imported instances requires another type class implicitly then compiler deprioritizes it:
summon[Typeclass[SomeType]].act(...
/ \
/ \
[ import X.given ] [ import Y.given ]
/ \
/ \
object X { object Y {
given imp1[T]: Typeclass[T] given imp2[T: AnotherTypeClass]: Typeclass[T]
[ THIS IS SELECTED ]
If type classes are implemented using Magnolia in scala3 we can't do the same trick and add dependency from join on AnotherTypeClass because those methods are implementing Magnolia's trait:
we can't achieve the same using mirror: Mirror.Of[A] instance, or throwing an exception.
Potential solution may be trying to write completely unrelated to Magnolia instance using raw macros like in scala2 and aborting it. But the problem is that we can't make dependency from MagnoliaTypeClass to AnotherTypeClass like we did in scala2
The text was updated successfully, but these errors were encountered:
In order to migrate all modules that use EnumType[] to scala3 (e.g. bigquery, avro) one aspect should be implemented in scala3 that is in place in scala2 implementation.
How Magnolia work with implicits in scala2
If compiler detects the same type of implicits imported from two scopes it fails with "could not find implicit value for parameter" error:
If one of those imported instances requires another type class implicitly then compiler still fails treating both implicits with an equal priority:
Even if implicit for
AnotherTypeClass
is not fulfilled, or even if it provided by native macro that aborts in such case:It fails with the same error. It fails even if
imp2
defined as depending on type class implemented in Magnolia:Which is defined as:
That depends on
AnotherTypeClass
in the definition ofdef join[T: AnotherTypeClass]
But if the first implicit is defined with Magnolia macro as well then it is supposed to work like this:
imp2
is aborted ingenMacro
by some condition forT
soimp1
is chosenT
is product with fields of other types likeQ
, for that typeimp2
is chosenAnotherTypeClass
is used to differentiate types and turn ON or OFF a macro.Apparently this is how macros are generated to Java. Decompiled Java sources might be checked to see why and how exactly Magnolia is switching between implicits, because Scala itself doesn't provide this way.
How Magnolia work with implicits in scala3
If compiler detects the same type of implicits imported from two scopes it fails with "Ambiguous given instances" error:
If one of those imported instances requires another type class implicitly then compiler deprioritizes it:
If type classes are implemented using Magnolia in scala3 we can't do the same trick and add dependency from
join
onAnotherTypeClass
because those methods are implementing Magnolia's trait:As opposed to duck typing approach in scala2. Even when intercepting Magnolia's
derivedMirror
like this:we can't achieve the same using
mirror: Mirror.Of[A]
instance, or throwing an exception.Potential solution may be trying to write completely unrelated to Magnolia instance using raw macros like in scala2 and aborting it. But the problem is that we can't make dependency from
MagnoliaTypeClass
toAnotherTypeClass
like we did in scala2The text was updated successfully, but these errors were encountered: