-
Notifications
You must be signed in to change notification settings - Fork 219
unify Combine and CombineTypes #2651
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
base: main
Are you sure you want to change the base?
Changes from 22 commits
b66de13
e07a39e
068d623
bb59a38
f7c03e3
d21abae
be4ea39
11a7b3c
8050d24
8fe9623
e7b55f0
20dfebd
5933b6a
79d0da8
189d572
0bcc84d
0ecadb1
400549e
43a8741
5f51a3f
7a5bca8
7864ec9
d7b782c
53a5a3d
df0330c
aa6fd30
c942a3d
87845fa
9557e57
5cfc83c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -801,34 +801,22 @@ infer typer = loop | |
Combine _ mk l r -> do | ||
_L' <- loop ctx l | ||
|
||
let l'' = quote names (eval values l) | ||
|
||
_R' <- loop ctx r | ||
|
||
let r'' = quote names (eval values r) | ||
let _L'' = quote names _L' | ||
|
||
xLs' <- case _L' of | ||
VRecord xLs' -> | ||
return xLs' | ||
let l' = eval values l | ||
|
||
_ -> do | ||
let _L'' = quote names _L' | ||
let l'' = quote names l' | ||
|
||
case mk of | ||
Nothing -> die (MustCombineARecord '∧' l'' _L'') | ||
Just t -> die (InvalidDuplicateField t l _L'') | ||
_R' <- loop ctx r | ||
|
||
xRs' <- case _R' of | ||
VRecord xRs' -> | ||
return xRs' | ||
let _R'' = quote names _R' | ||
|
||
_ -> do | ||
let _R'' = quote names _R' | ||
let r' = eval values r | ||
|
||
case mk of | ||
Nothing -> die (MustCombineARecord '∧' r'' _R'') | ||
Just t -> die (InvalidDuplicateField t r _R'') | ||
let r'' = quote names r' | ||
|
||
-- The `Combine` operator should now work on record terms and also on record types. | ||
-- We will use combineTypes or combineTypesCheck below as needed for each case. | ||
let combineTypes xs xLs₀' xRs₀' = do | ||
let combine x (VRecord xLs₁') (VRecord xRs₁') = | ||
combineTypes (x : xs) xLs₁' xRs₁' | ||
|
@@ -845,7 +833,45 @@ infer typer = loop | |
|
||
return (VRecord xTs) | ||
|
||
combineTypes [] xLs' xRs' | ||
let combineTypesCheck xs xLs₀' xRs₀' = do | ||
let combine x (VRecord xLs₁') (VRecord xRs₁') = | ||
combineTypesCheck (x : xs) xLs₁' xRs₁' | ||
|
||
combine x _ _ = | ||
die (FieldTypeCollision (NonEmpty.reverse (x :| xs))) | ||
|
||
let mL = Dhall.Map.toMap xLs₀' | ||
let mR = Dhall.Map.toMap xRs₀' | ||
|
||
Foldable.sequence_ (Data.Map.intersectionWithKey combine mL mR) | ||
|
||
-- If both sides of `Combine` are record terms, we use combineTypes to figure out the resulting type. | ||
-- If both sides are record types, we use combineTypesCheck and then return the upper bound of two types. | ||
-- Otherwise there is a type error. | ||
case (_L', l', _R', r') of | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously we threw a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's think about what error behavior we need. The new operator
I will work on this tomorrow. It's definitely feasible to implement detailed error messages here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the last case, maybe something like:
Also, for the other cases we probably want a similar error message if both arguments are neither record term nor record type; For example if the expression was There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need unit tests for all those cases. I don't see any unit tests. Right now, an incorrect use of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that would be great! Thank you for working on this! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have changed the error messages, making them more detailed. I also added some unit tests to verify that those error messages are actually being generated. For instance, the tests verify that errors for the |
||
(VRecord xLs', _, VRecord xRs', _) -> do | ||
combineTypes [] xLs' xRs' | ||
|
||
(VConst cL, VRecord xLs', VConst cR, VRecord xRs') -> do | ||
let c = max cL cR | ||
combineTypesCheck [] xLs' xRs' | ||
return (VConst c) | ||
|
||
(_, _, VRecord _, _) -> do | ||
case mk of | ||
Nothing -> die (MustCombineARecord '∧' l'' _L'') | ||
Just t -> die (InvalidDuplicateField t l _L'') | ||
|
||
(_, _, VConst _, _) -> do | ||
case mk of | ||
Nothing -> die (MustCombineARecord '∧' l'' _L'') | ||
Just t -> die (InvalidDuplicateField t l _L'') | ||
|
||
_ -> do | ||
case mk of | ||
Nothing -> die (MustCombineARecord '∧' r'' _R'') | ||
Just t -> die (InvalidDuplicateField t r _R'') | ||
|
||
|
||
CombineTypes _ l r -> do | ||
_L' <- loop ctx l | ||
|
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.
Maybe we can pull this out of
look
and use it in both theCombine
andCombineTypes
cases?Also, can we rename this to something more meaningful like
checkForFieldCollisions
?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.
Will do.