Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Summoning a typeclass in a macro #12404

Discussion options

(from gitter)

I'm having a slight problem understanding the behaviour of summoning in macro. I have a method which takes a given parameter (def myMethod[T: MyTypeclass]), I can use it in a macro as follows:

'{myMethod[f](${Expr.summon[MyTypeclass[f]].get})}

the f here is a type of a case class field, and the type parameter is obtained using the field.tpe.asType match case '[f] => ... trick, though I don't think that's relevant here. The important part is that I have a Type[f] instance.

So for a concrete invocation we have e.g. f == String and the appropriate typeclass is summoned.
However, if I do either:

'{myMethod[f]} // or
'{myMethod[tf.Underlying]} // where tf: Type[f]

I get an error, that a given MyTypeclass[f] cannot be found (with the abstract type f/tf.Underlying, instead of the concrete one). Why do I have to spell out the givens explicitly?

You must be logged in to vote

Could you show a complete example? This might be a bug.

Replies: 2 comments 7 replies

Comment options

Could you show a complete example? This might be a bug.

You must be logged in to vote
7 replies
Comment options

Thanks. Though I don't really understand why during typechecking of the quoted code '{myMethod[T]} dotty tries to search for MyTypeclass[T] instead of MyTypeclass[String] (where at invocation-site, we have T == String)?

If I'm understanding the docs correctly, the T in '{myMethod[T]} is in fact a splice - sth like an equivalent of '{myMethod[${summon[Type[T]].Underlying}]}. So I'd expect the T to be substituted with String before the typechecking is done - and hence having the correct implicit instance looked up.

Comment options

Though I don't really understand why during typechecking of the quoted code '{myMethod[T]} dotty tries to search for MyTypeclass[T] instead of MyTypeclass[String] (where at invocation-site, we have T == String)?

'{myMethod[T]} is type-checked in testImpl where we do not know the concrete type of T. It is not type-checked at the invocation site.

Comment options

'{myMethod[T]} is type-checked in testImpl where we do not know the concrete type of T. It is not type-checked at the invocation site.

Ok, thanks, though I'm still confused ;) I thought that the T in there is an incognito splice of whatever is represented by the implicit Type[T], which would mean that we know very well what's the concrete type. I'll re-read the docs :)

Comment options

Long story short:

  • We type check '{myMethod[T]} using T and the knowledge of its bounds (>: Nothing <: Any in this case)
  • When we expand the macro with T =:= String we simply replace T with String. No need to retype check.
Comment options

Thanks, my mental model which assumed T meant +/- $T (splicing) was wrong then. Or maybe not wrong, but it happens later - typechecking comes first, and splicing happens only after that's done. Thanks again for the patience :)

Answer selected by nicolasstucki
Comment options

Use compiletime.summonInline. This delays the search until after the macro is expanded.

That doesn't sound quite true. It looks like summonInline is expanded earlier in some cases.
See the discussion here: typelevel/cats-tagless#556 (comment)

In this case we are transforming a trait inside the macro:

 trait ShowFAlgebra[F[_]]:
 def showF[A: Show](a: A): F[String]
 def showAll[A: Show](as: A*): F[String]
 def showProduct[A: Show](a: A): F[(A, String)]
 def logF[A: Show](message: => A): F[Unit]
 object ShowFAlgebra:
 given Aspect.Function[ShowFAlgebra, Show] = Derive.aspect

But inside the Derive.aspect macro, when we are generating the body of methods like showF, we can't access the Show[A] from the implicit parameters of the method itself.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /