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

Compile-time conditional implicit (if fails, continue implicit search) #15895

Unanswered
adamw asked this question in Metaprogramming
Discussion options

Is there a way to define an implicit value, but only if a compile-time condition is met, so that the implicit search continues (using lower-precedence values) if the condition is false?

This would be trivial if not for the second part: the inline/macro can simply report a compile-time error if the condition is false and be done with it. However, I'd like to define a special-case implicit for which a compile-time check needs to be done.

I've tried with transparent implicits, sth like:

enum MyCondition[T]:
 case Yes[T] extends MyCondition[T]
 case No[T] extends MyCondition[T]
transparent implicit inline def checkMyConditon[T]: MyCondition[T] = 
 /* macro which checks the condition based on T */
// the special-case implicit:
implicit inline def mySpecialImplicit[T](using MyCondition.Yes[T]) = 
 /* another macro */

However, despite being transparent, and despite returning the right sub-type from the macro implementation, the Yes implicit is never found.

Even a simple implicitly[MyCondition.Yes[T]]] fails, so I guess the type of transparent implicits isn't refined before implicit search resolution?

But maybe there's another way to define a conditional implicit as described above?

You must be logged in to vote

Replies: 1 comment 3 replies

Comment options

Not completely sure what you are trying to do. Can you give an example of what you want to happen and what happens currently?

You must be logged in to vote
3 replies
Comment options

Sure, I'll try at least :)

I've got a macro which derives the Schema typeclass for any type T (it's implemented using Magnolia, but that's not really relevant I think).

Now I'd like to define another macro, which derives a Schema instance, but only for enums where all implementaitons are parameter-less. This isn't a condition I can express using type bounds - I need a compile-time check in a macro, if this derivation is at all applicable. If not, I want to continue the implicit search using the default mechanism - checking all the other available scopes.

My idea to constraint this special-case macro was to give it an implicit parameter, which would only be derived for parameter-less enums - which is demonstrated above using checkMyCondition. But I couldn't get it to work (using transparents etc.)

Comment options

+1 for the same problem.

Are things changed now?

Comment options

I have found a technique.

Let you want to generate a value MyTypeclass[T].

At first, you define helper type:

sealed trait MyTypeclassBuildResult[T]
case class MyTypeclassBuildSuccess[T](value: T) extends MyTypeclassBuildResult[T]
case class MyTypeclassBuildFailure[T](message: String) extends MyTypeclassBuildResult[T]

then create the search logic, which return Failure when search is impossible. It should be transparent inline.

transparent inline given tryBuildMyMypeclass[T](...): MyTypeclassBuildResult[T]

And then

inline given buildMyTypeclass[T,R <: MyTypeclassBuildResult](using inilne r:R, inline ev: R =:= MyTypeclassBuildSuccess[T]) = 
 r.value

Example: https://github.com/rssh/scala-appcontext/blob/main/tagless-final/shared/src/main/scala/com/github/rssh/appcontext/AppContextAsyncProviders.scala

Blogpost with description (the same as below): https://github.com/rssh/notes/blob/master/2024_12_30_dependency_injection_tf.md

i.e. difference in evidence, which can be found or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet

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