-
Notifications
You must be signed in to change notification settings - Fork 44
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
inexhaustive pattern examples in error messages #1139
base: dev
Are you sure you want to change the base?
Conversation
Theoretical(?) basis: A case expression is necessarily inexhaustive => some value(s) of the given type satisfy it => there is some non-empty subset of final expressions of the given type that does not satisfy the final constraint, but satisfies its dual. Next we will show (inductively) that for a consistent dual (sometimes represented as a list of constraints here), there is always some constraint that, obviously, can be emitted from a single pattern that once that constraint is satisfied, the entire dual is satisfied.
Base case 1: the dual is a Base case 2: the dual is a conjunction of
Recursive cases:
The dual is a conjunction of The dual is a conjunction of |
@@ -1,6 +1,10 @@ | |||
open Sets; | |||
|
|||
let is_inconsistent_int = (xis: list(Constraint.t)): bool => { | |||
type b = |
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.
A temporary type defined to simulate bool
. If some value of b
!= True
, that indicates that some constraint is consistent, and an additional Constraint
is kept track of such that once it's satisfied, some dual is satisfied.
It's used to make the changes trackable, but it might be more intutive to change the signature of is_exhaustive = (xi: Constraint.t): bool
to satisfy = (xi: Constraint.t): option(Constraint.t)
and this auxillary type can be got rid of (drastic change!).
src/haz3lcore/dynamics/Incon.re
Outdated
switch (is_inconsistent(Constraint.[dual(truify(xi))])) { | ||
| True => true | ||
| False(xi) => | ||
print_endline(Constraint.show(xi)); |
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 auxilliary constraint is printed to the console.
If the basis above works, the next step would be to reverse the auxilliary constraint into a |
…lgrove/hazel into hazel-inexhaustive-patterns
…lgrove/hazel into hazel-inexhaustive-patterns
For when I do get it to work, we need to think about the UI design for large error messages like these where the message gets cut off. Maybe a toggle that makes the bottom bar larger to show the full message when it exceeds the length of the display? Thoughts @disconcision ? Also, given the above problem is solved, how hard would it be to list all of the cases that aren't matched, rather than just one example? |
@cyrus- to start maybe have a short and long version of messages, with the short version having some affordance at the end e.g. ellipses indicating there's more. clicking on the affordance, or maybe just anywhere in the message part of the bar, could cause the bar to expand to take up more lines. clicking again makes it a single line again. similarly but alternatively, you could make the bar's expanded state triggered on hover, and while hovered, show an additional pin icon that could be pressed to make the expanded state stick until unpinned. (for this particular error, it would be nice if we could eventually show it inline... an 'angry ghost' of an unhandled case below the last case) |
This pull request aims to produce a more verbose error displayed by the implementation of the exhaustiveness checking feature mentioned in “Live Pattern Matching with Typed Holes (https://victoryyw.github.io/assets/pdfs/pattern.pdf)”.
If a case expression is necessarily inexhaustive (i.e.: the expression will necessarily fail to match all values of the type of its scrutinee), the expression will be wrapped with an error hole like in Fig. 2b in the paper. This is done by using an error_exp called InexhaustiveMatch (created in #1114), which behaves uniquely when supplied to CursorInspector.re. We aim to supplement the produced error hole to display a pattern that can be produced by the case expression’s scrutinee but is not matched by any of the branches of the case expression.
This is planned to be done by utilizing the final constraint generated to produce the inexhaustive error and inverting it ( using the dual of the constraint ). The inverted constraint should include patterns that are not matched and therefore we can map the constraint to a pattern to be displayed on the error interface.