Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
This PR originally implemented the "Unify by
Ident.Idx
" solution, but then I realized it was kinda a non-starter. Currently, this PR is WIP.Background
In Elm's compiler, two rigid variables unify only if the
Var
s point to the exact same descriptor. This works because Elm creates and re-uses the sameVar
for the same rigid vars during instantiate. In Roc, this works fine for regular rigid vars, but this presents a problem in our specialized representation ofNum
.Problem
Given this type:
We want
a
to refer to the same rigid var and unify with the other rigid vars in the signature. In our current system, this looks like:Since these rigid vars are not referencing other
Var
s, we can't unify by identical descriptor – so it's unclear how exactly these should unify.Possible Solutions
Unify by
Ident.Idx
We could update the variable instantiation to be:
Then, update the unification logic to allow two rigid vars to unify if they point to the same
Ident
. This almost works, but for the fact that eachIdent
is intended to refer to exactly one thing (evidenced by theRegion
on eachIdent
), so reusing idents here seems like a non-starter.Change how we represent
Num
If we changed how we represented
Num
back to a type-apply-y approach, while still only supporting our explicit builtins, we could do something like:Then, we could unify sub variables normally and rely on regular rigid var semantics and every would Just Work.
However, this results in 3 type descriptors and vars needed to represent a single number, which is against the goal of more compact number representations. That said, this feels like the best option right now, imo.
Group equal rigid vars (not fleshed out)
In a function signature (and its def for scoped typed variables), we could somehow capture equal sets of rigid vars (ie all vars that are
a
). Then if this set-thing was passed to unify (maybe thru Scratch) we could allow rigid var idents to unify if they're equal. This might require an additional allocation tho, and adds extra work to how equal rigid vars are managed by Can/Solve. It's unclear to me how good/bad of an idea this is.Something else
There are probably other solutions here to that I'm not thinking of!!