Match query type variables against concrete types#488
Merged
Conversation
A type search for `a -> HTMLElement` previously returned no concrete results where `_ -> HTMLElement` matched functions like `HTMLAnchorElement -> HTMLElement`, because compareTypes had no case for a query-side type variable against a concrete type (#395). Query variables now match any concrete type, as wildcards do, except that each instantiation charges a penalty of 1 - less than a single unit of structural mismatch (10) - so results that unify with the query directly still rank first. Each instantiation is also recorded against the variable's name and fed through typeVarPenalty, so repeated query variables must be instantiated consistently: for the query `a -> a`, `Int -> Int` ranks above `Int -> String`. Existing comparisons are unaffected: no previously-matching clause changed, so current rankings only gain new, lower-ranked results. Also fixes the compareTypes doc examples, which had a typo (parseType s2 twice) and a stale expected score predating the 10x score scaling. Based on #396 by @klntsky.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Fixes #395. Supersedes #396 — the approach is @klntsky's; this builds on that patch and addresses the ranking comments raised in that PR.
Problem
A type search for
a -> HTMLElementreturns no concrete results, while_ -> HTMLElementmatches functions likeHTMLAnchorElement -> HTMLElement.compareTypeshad no case for a query-side type variable against a concrete type, so such comparisons fell through toNothing.The approach in 396
#396 made a query variable match any concrete type, but this had two related issues:
a -> awould scoreInt -> Stringidentically toidentity— repeated variables lose their consistency constraint, because thetypeVarPenaltymachinery never sees var-to-concrete matches.a -> bwould rankInt -> Int(score 0) strictly aboveforall x. x -> x(score 3) — an arbitrary concrete function beating the closest polymorphic match.The blocker at the time was penalty headroom, but since then Pursuit has added it control:
calculatescales structural scores by 10, leaving room for penalties smaller than one structural unit.This change
A query variable matches any concrete type, as wildcards do, except:
(variable, rendered type)pair and fed through the existingtypeVarPenalty, so repeated query variables must be instantiated consistently.The resulting gradient for query
a -> a:x -> x(0) <Int -> Int(2) <Int -> String(3). For #395's query,forall e. (...) => e -> HTMLElementranks at 0 and concreteHTMLAnchorElement -> HTMLElementright behind at 1.