Solve union constraints backwards#3720
Conversation
The union solver for `Union l r u` was missing the case when `r` and `u` are literals (which should solve, according to the fundeps, and indeed is possible to solve).
|
I think the solver portion looks good. As for tests, I think it's fine to keep them in this module, but maybe something like: solveL :: forall l r u. Union l r u => RProxy r -> RProxy u -> RProxy l
solveL _ _ = RProxy
solveUnionBackwardsNil :: RProxy ()
solveUnionBackwardsNil = solveL (RProxy :: _ ()) (RProxy :: _ ())
...etc |
Conflicts: src/Language/PureScript/TypeChecker/Entailment.hs
|
Fix the conflict and add an entry to the changelog and we can merge this, yeah? |
|
Sounds good to me 👍 |
|
@MonoidMusician Just FYI. I've submitted a PR that fixes the merge conflict and adds a changelog entry in MonoidMusician#1 |
|
Thanks!! I'll take a look in a week after I'm done with my semester. |
|
Will this PR will make it into the next release? I'm not trying to rush this, but just to clarify, the merge conflict is quite simple (spaces added to better compare differences): If we merge the two lists together and remove the unneeded import While the conflict could be resolved here, I wasn't sure whether that would be rude to do so (hence my PR). Even if the conflict is solved here, a commit adding this change to the changelog would still need to be pushed. Lastly, I'm not sure how this would be affected by #4090. |
|
Any updates on this? |
Conflicts: src/Language/PureScript/TypeChecker/Entailment.hs
|
Thanks for your patience! I'm sorry I got busy, but I feel good about this now. I ran HLint and fixed the one linter issue I introduced. I also ran more test cases in the REPL and it works exactly like I would expect, include failure cases. Do you want to include this in the next release or merge it after? |
The union solver for
Union l r uwas missing the case whenranduare literals (which should solve, according to the fundeps, and indeed is possible to solve).I don't believe there's an existing issue for this, which means it potentially went unnoticed for two years …
So according to my limited understanding, these solving methods return the "new" values of the type heads, which get unified with the old ones. How my algorithm works is that, when
randuare literals, we try to partitionuinto the labels that belong tor(which are at the tail ofu) and the remaining that belong tol. These then must get unified with the original values in order to make progress solving the constraint. In particular, iflis a variable, it will get set to the value that makes it all work. Note that if there are labels present inrthat are not present inuwe must fail (guard (null leftover)).Is my understanding of the solver accurate? Feedback is more than welcome!
I also need advice on where best to put the tests! I will add more tests, but I'm reasonably confident that it works at this stage. In particular, it seems to work very well for the use case @masaeedu and I had (which relies integrally on solving this constraint backwards).