-
Notifications
You must be signed in to change notification settings - Fork 571
Type-level integers #4207
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
Type-level integers #4207
Conversation
Co-authored-by: Csongor Kiss <kiss.csongor.kiss@gmail.com>
Co-authored-by: Csongor Kiss <kiss.csongor.kiss@gmail.com>
Co-authored-by: Csongor Kiss <kiss.csongor.kiss@gmail.com>
|
Regarding the names: there was some discussion that it would be nice to actually rename I suppose the problem is that we don't have dedicated natural literals at the term level, so it quickly gets to be a lot of work, sorry. |
JordanMartinez
left a comment
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.
Just some initial comments as I looked through this.
|
@MonoidMusician So, if I understand correctly, we can introduce term-level Naturals to mirror the relationship between String and Symbol, right? e.g. Prim introduces the Natural type, then It's definitely quite a lot of work but I do think that this would be pretty nice. |
|
I don't see the point of dedicated More broadly, and probably more controversially, should we be adding new type-level literals ad-hoc like this? As @MonoidMusician reminded us, we're already possibly regretting the separation between class IsReflectable t v | v -> t where
reflectType :: forall proxy. proxy v -> twhich would subsume both I bring this up because, if the compiler is going to implement |
Personally, I think that having separate type classes for these operations is much more intuitive than having different fundeps provide different solutions. Row.Cons, for example, is an example of a pretty overloaded type class whose name doesn't really help make its purpose understandable. If we could rename Add/Mul to something that reflects that it can also solve Sub/Div, I'd definitely be more inclined towards this.
We already 2/5 of the non-container literals at the type-level (Boolean, String/Symbol), and so far we've only really gotten it "right" with
For use-cases that require non-negative numbers, I agree that |
I'm not sure, but how would you implement |
|
No no, in a |
|
I know I already said it, but I'm for By class NonZero :: Int -> Constraint
class NonZero i
instance Fail (Text "Got a zero!") => NonZero 0
else instance NonZero (i :: Int)Could the same thing be achieved via an class IsZero :: Int -> Boolean -> Constraint
class IsZero i b | i -> b
class (IsZero i False) <= DivMod ... |
|
Re My reluctance for including
Our options are:
The reason I keep saying to hold off on |
Good point. Correct me if I'm wrong, but can't |
Yes, although I haven't added solving for the
I'd be more than happy to do this as well. I think having a dedicated issue for it would flesh out the implementation better. Correct me if I'm wrong, but this should be the final sets of primary changes right? I hope I'm not forgetting anything that was discussed a few weeks back 😄. |
|
So, have we reached consensus that the following changes need to be made before this PR will be merged?
|
This allows the type-level Boolean and Ordering types to be solved.
JordanMartinez
left a comment
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.
LGTM!
I marked this PR as a breaking change, but I can't recall why. I think it's only breaking to users of the compiler as a library, but not breaking like ES modules breaking.
|
@JordanMartinez I believe it was solely because of the introduction of the |
|
I'll be merging |
|
Looks like there's another merge conflict due to #4239. |
rhendric
left a comment
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.
Other changes all look good—I think if you just make that one case expression unconditional and add an appropriate test, I can approve this.
This fixes a bug where arithmetic facts aren't taken into account when solving nominal `Compare` constraints. The test included in this commit exercises this change, whereas previously, it'd fail when solving `Compare a 10 LT`.
|
Test failures are related to the bundler because of 516abc2, it seems like. Tests for type-level ints are all passing. |
|
Yes, sorry, these failures are indeed not your fault. Because ES module support is currently in development, the tests currently depend on some temporary forks of PureScript libraries that have been changed to be compatible with the new module format, and those forks are getting some cowboy commits at the moment that are breaking everyone else. This will affect local and CI builds (if your local build isn't affected yet, it's because your cached test dependencies haven't expired yet—you have at most a day before this affects you). Please stand by while we restore order. |
|
CI builds now. |
rhendric
left a comment
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.
Nice work.
Co-authored-by: Ryan Hendrickson <ryan.hendrickson@alum.mit.edu>
This PR implements type-level integers for PureScript and resolves #2899. This builds against latest
masterinstead of #3058 as rebasing would be pretty tedious. Type-level integer literals would be kinded as theInttype so breakage should be fairly minimal, but it's probably best that this would be merged in a major release.Here's an example of what this makes possible:
For further discussion:
Pow/RootSub/Div/ModIntvsIntegerfor the backend. Having reflection means thatNats are bounded to the upper limit for JS, so the currentIntegerbackend is a bit overkill for this.Checklist: