-
Couldn't load subscription status.
- Fork 1.1k
Compile-time conditional implicit (if fails, continue implicit search) #15895
-
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?
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment 3 replies
-
Not completely sure what you are trying to do. Can you give an example of what you want to happen and what happens currently?
Beta Was this translation helpful? Give feedback.
All reactions
-
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.)
Beta Was this translation helpful? Give feedback.
All reactions
-
+1 for the same problem.
Are things changed now?
Beta Was this translation helpful? Give feedback.
All reactions
-
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
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.
Beta Was this translation helpful? Give feedback.