-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add RuntimeConstraint #175
Changes from 5 commits
53ad033
fd7e919
e2d9ca8
e0e0bdd
ea590ff
6728342
76efae0
b5d4ba9
1538ffa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package io.github.iltotore.iron | ||
|
||
import scala.util.NotGiven | ||
|
||
final class RuntimeConstraint[A, T](_test: A => Boolean, val message: String): | ||
inline def test(value: A): Boolean = _test(value) | ||
|
||
object RuntimeConstraint: | ||
|
||
inline def derived[A, C](using inline c: Constraint[A, C]): RuntimeConstraint[A, A :| C] = | ||
new RuntimeConstraint[A, A :| C](c.test(_), c.message) | ||
|
||
final class AutoDerived[A, T](val inner: RuntimeConstraint[A, T]) | ||
object AutoDerived: | ||
inline given [A, C](using rtc: RuntimeConstraint[A, A :| C]): AutoDerived[A, A :| C] = | ||
new AutoDerived[A, A :| C](rtc) | ||
|
||
inline given [A, C](using inline c: Constraint[A, C], ng: NotGiven[RuntimeConstraint[A, A :| C]]): AutoDerived[A, A :| C] = | ||
new AutoDerived[A, A :| C](RuntimeConstraint.derived[A, C]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One of the things that was bugging me was having auto-derivation of With this, a user / method / etc can define whether they want an explicit or implicit given to be provided. For newtypes, this is generated by default Example: // will raise a compile-time error if one isn't explicitely defined (newtypes are OK since we create one for them in RefinedTypeOpsImpl)
def foo(value: Int)(using RuntimeConstraint[Int, Int :| Greater[10]]) = ???
// Will prioritise an explicitly defined RuntimeConstraint and auto-derive one if it doesn't exist
def foo(value: Int)(using RuntimeConstraint.AutoDerived[Int, Int :| Greater[10]]) = ??? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still don't understand why def foo(value: Int)(using RuntimeConstraint[Int, Greater[10]]) = ???
def foo(value: Int)(using RuntimeConstraint.AutoDerived[Int, Greater[10]]) = ??? Also, I'm not sure about the usefulness of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After sleeping on it, I think you're right. I reverted these changes |
||
|
||
end RuntimeConstraint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need such given instance. If someone want to get the constraint bound to a newtype, it can do it as follow:
But we can get
rtc
as a publicval
to allow using it inRefinedTypeOps
extensions like in Cats or ZIOThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made it a
val
but also created aprotected given RuntimeConstraint[A, C]
. My reasoning behind having theprotected given
is so that it can be used in the companion object of opaque types when creating codecs etc