Open
Conversation
nigredo-tori
commented
Mar 22, 2026
Comment on lines
+50
to
+57
| * `gen` will make an effort to keep the resulting value's type as narrow as possible, which can be useful for typeclass families. As a | ||
| * contrived example, when configured with `type Typeclass[x] = Either[Any, x]` and corresponding `join` and `split`, `gen` may derive an | ||
| * `Either[String, T]` if the target type and available instances allow it. To take advantage of it, one has to define `join` and `split` | ||
| * in such a way that they propagate narrowed typeclasses as appropriate: | ||
| * | ||
| * {{{ | ||
| * def join[L, T](caseClass: CaseClass[Either[L, *], T]): Either[L, T] | ||
| * }}} |
Comment on lines
+867
to
+881
| val prefixType = c.prefix.tree.tpe | ||
| val prefixObject = prefixType.typeSymbol | ||
|
|
||
| val TypeClassNme = TypeName("Typeclass") | ||
| val typeDefs = prefixType.baseClasses.flatMap { baseClass => | ||
| baseClass.asType.toType.decls.collectFirst { | ||
| case tpe: TypeSymbol if tpe.name == TypeClassNme => | ||
| tpe.toType.asSeenFrom(prefixType, baseClass) | ||
| } | ||
| } | ||
| val typeclass = typeDefs.headOption.fold( | ||
| c.abort(c.enclosingPosition, s"the derivation $prefixObject does not define the Typeclass type constructor") | ||
| )(_.typeConstructor) | ||
|
|
||
| TypeConstructor(typeclass, appliedType(typeclass, _)) |
Author
There was a problem hiding this comment.
This was previously done in gen.
Comment on lines
+893
to
+895
| s"""expected a * -> * HKT, | ||
| |got: $tpe as ${showRaw(tpe)} | ||
| |eta-expanded: ${tpe.etaExpand} as ${showRaw(tpe.etaExpand)}""" |
Author
There was a problem hiding this comment.
This is probably too verbose, but I feel like the more information we get here the better. The end users probably wouldn't see this error.
|
|
||
| import magnolia1._ | ||
|
|
||
| // Slimmed down version of schema derivation from the Caliban library. |
Author
| assert(error contains """ | ||
| |magnolia: could not find Show.Typeclass for type Double | ||
| assert(clue(error) contains """ | ||
| |magnolia: could not find magnolia1.examples.Show.Typeclass[Double] |
Author
There was a problem hiding this comment.
The error messages were changed to fully show the required type.
Comment on lines
+34
to
+35
| implicit def genNarrow[Tc[_] <: CollectFields[Any, _], A]: Tc[A] = | ||
| macro Magnolia.genNarrow[Tc, A] |
Author
There was a problem hiding this comment.
I'd like to be able to write
implicit def genNarrow[Out, A]: CollectFields[Out, A] =
macro Magnolia.genNarrow[CollectFields[Out, *], A]However, for whatever reason, this seems to lose the information about what Out actually is.
Wrapping the whole thing in another macro (as in the schema example) seems to solve this, but it's a weird magical workaround for what looks like a compiler bug.
0774aae to
e9478f8
Compare
e9478f8 to
dd19157
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See #627.
It's difficult to narrow recursive instances, especially in Scala 2 where we don't constrain
joinandsplitsignatures. The most robust solution (although not the most convenient) is to give the users a way to manually specify the desired typeclass.This PR adds a new macro,
genNarrow, that does just that. It reuses most of the implementation ofgen, but replaces uses ofTypeclasswith a specified* -> *HKT.