Closed Iltotore closed 12 months ago
This should work (waiting for the nightly version) but perhaps it would be better to grant access to the given instance (to avoid re-synthesis)?
perhaps it would be better to grant access to the given instance
If we do that, the given instance would leak. For example, this code would compile:
import io.github.iltotore.iron.*
import io.github.iltotore.iron.constraint.Positive
opaque type Temperature = Int :| Positive
object Temperature extends RefinedTypeOps[Int, Positive, Temperature]
//No explicit iron import
import foo.Temperature
summon[RuntimeConstraint[Int, Positive]] //Works
which is not the expected behaviour. Also I'm afraid this would cause other ambiguous given errors:
opaque type Temperature = Int :| Positive
object Temperature extends RefinedTypeOps[Int, Positive, Temperature]
opaque type Moisture= Int :| Positive
object Moisture extends RefinedTypeOps[Int, Positive, Moisture]
import foo.{Moisture, Temperature}
summon[RuntimeConstraint[Int, Positive]] //Ambiguous given errors: both Moisture.rtc and Temperature.rtc are eligible
(to avoid re-synthesis)
the inline def does not re-synthetize nor add any overhead on top of the protected given RuntimeConstraint
. The method call is erased after compilation.
(to avoid re-synthesis)
I am using RuntimeConstraint
to define typeclass instances for constrained opaque
types. These instances need to be defined explicitly to work with Scala 3 auto derivation (for types using the constrained type). Having access to the RuntimeConstraint
within the companion object would avoid re-synthesis.
I think protected
access will support mine and the other use cases. Right?
From the workaround in the ticket,
type IsWhole = GreaterEqual[0]
opaque type Whole <: Int = Int :| IsWhole
object Whole extends RefinedTypeOps[Int, IsWhole, Whole]:
given Parse[Whole] =
summon[Parse[Int]].refineParse(using rtc)
I would like to avoid having to specify the given instance (using rtc
) and reuse the one from RefinedTypeOps
.
given Parse[Whole] =
summon[Parse[Int]].refineParse
You shouldn't have to. That's why the protected
is given
This code compiles with this PR:
import io.github.iltotore.iron.*
import io.github.iltotore.iron.constraint.numeric.GreaterEqual
trait Parse[A]:
def refineParse[C](using contraint: RuntimeConstraint[A, C]): Parse[A :| C] = ???
given Parse[Int] = new Parse[Int]{}
type IsWhole = GreaterEqual[0]
opaque type Whole <: Int = Int :| IsWhole
object Whole extends RefinedTypeOps[Int, IsWhole, Whole]:
given Parse[Whole] = summon[Parse[Int]].refineParse
Thanks for checking.
I was getting compiler errors (something about deferred inline) with inline
instances but that could have been my code.
No problem. Feel free to open a new discussion or issue if you have hard time dealing with this error.
Closes #178
@ajaychandran can you check if this PR solves your problem?