-
Notifications
You must be signed in to change notification settings - Fork 82
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
Remove unneeded parenthesis #203
Conversation
e.g. `(Int a)` to `Int a`
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.
This looks amazing! I only have one comment related to the precedence of Int a
and Float a
src/types/mod.rs
Outdated
TypeApplication(ctor, _) if ctor.is_polymorphic_int_type() => TypePriority::MAX, | ||
TypeApplication(ctor, _) if ctor.is_polymorphic_float_type() => TypePriority::MAX, |
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.
TypeApplication(ctor, _) if ctor.is_polymorphic_int_type() => TypePriority::MAX, | |
TypeApplication(ctor, _) if ctor.is_polymorphic_float_type() => TypePriority::MAX, |
These cases should be removed I think. I haven't looked at it in a bit but I'm assuming these must have been included because of an existing parsing issue or similar but the intention was for Int a
to parse like any other type application.
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.
Yes.
These branches give special treatment to polymorphic numeric types. If these branches were simply removed, the representation of concrete types such as I32
would always be accompanied by parentheses, as in (I32)
.
// removed `TypeApplication(ctor, _) if ctor.is_polymorphic_int_type() => TypePriority::MAX,`
examples/typechecking/bind.an: Actual stdout differs from expected stdout:
1| add_one : forall a. (Maybe I32 -> Maybe I32 can a)
| add_one : forall a. (Maybe (I32) -> Maybe (I32) can a)
..
4| x : Maybe I32
| x : Maybe (I32)
Is there any way to properly distinguish between these?
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.
Oh, good question! Yes, you can distinguish between them. So when you have Int I32
we try to display it as just I32
but internally it will still be TypeApplication(Type::Primitive(PrimitiveType::IntegerType), vec![i32 type])
. So you can check for that case specifically by checking what the type variable a
is bound to in Int a
(if it is bound).
You can find code that checks for this case in fmt_type_application
- the is_polymorphic_int_type
check on the constructor. Then you can see how fmt_polymorphic_numeral
afterward checks the type bindings on the first argument to see whether it is a type variable (unbound) or already bound to a type.
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.
The point raised have been corrected 💪
before: > foo : (Foo String Int a) > add_one : forall a. (Maybe I32 -> Maybe I32 can a) after: > foo : (Foo String (Int a)) > add_one : forall a. (Maybe I32 -> Maybe I32 can a) -- No change for concrete types refs: jfecher#203 (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.
Looks great, thank you!
refs #202
Remove redundant parentheses from the type display.
No changes have been made to effect(can) as no decision was made about it.
Algorithm.
Define the precedence of the binding of each syntactic element as follows.
primitives > application > forall > pair > fun
Note
The primitives includes generic Int/Float. Then the type
Foo String Int a
meansFoo String (Int a)
In the display, brackets are added if the priority of the current object is greater than the priority of its sub-element.
The following is pseudo code.
Result
For completeness_checking.rs the result is as follows:.
(,)
is right-associative, so the parentheses are removed.before.
after
For instantiation.rs the following applies.
(=>)
is also right-associative, so(a => (b => e))
becomesa => b => e
.before.
after.