Skip to content

Commit ae2310b

Browse files
authored
Fix #1001. (#1034)
1 parent 8de4808 commit ae2310b

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

src/TypeError.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ data TypeError = SymbolMissingType XObj Env
5151
| InvalidMemberTypeWhenConcretizing Ty XObj TypeError
5252
| NotAmongRegisteredTypes Ty XObj
5353
| UnevenMembers [XObj]
54+
| DuplicatedMembers [XObj]
5455
| InvalidLetBinding [XObj] (XObj, XObj)
5556
| DuplicateBinding XObj
5657
| DefinitionsMustBeAtToplevel XObj
@@ -232,6 +233,10 @@ instance Show TypeError where
232233
joinWithComma (map pretty xobjs) ++ "` at " ++
233234
prettyInfoFromXObj (head xobjs) ++
234235
".\n\nBecause they are pairs of names and their types, they need to be even.\nDid you forget a name or type?"
236+
show (DuplicatedMembers xobjs) =
237+
"Duplicate members: `" ++
238+
joinWithComma (map pretty xobjs) ++ "` at " ++
239+
prettyInfoFromXObj (head xobjs)
235240
show (InvalidLetBinding xobjs (sym, expr)) =
236241
"The binding `[" ++ pretty sym ++ " " ++ pretty expr ++ "]` is invalid at " ++
237242
prettyInfoFromXObj (head xobjs) ++ ". \n\n Binding names must be symbols."

src/Validate.hs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
module Validate where
22

3+
import Data.List (nubBy, (\\))
4+
import Data.Function (on)
5+
36
import TypeError
47
import Obj
58
import Types
@@ -19,13 +22,24 @@ validateMemberCases typeEnv typeVariables rest = mapM_ visit rest
1922

2023
validateMembers :: TypeEnv -> [Ty] -> [XObj] -> Either TypeError ()
2124
validateMembers typeEnv typeVariables membersXObjs =
22-
if length membersXObjs `mod` 2 == 0
23-
then mapM_ (okXObjForType typeEnv typeVariables . snd) (pairwise membersXObjs)
24-
else Left (UnevenMembers membersXObjs)
25+
checkUnevenMembers >> checkDuplicateMembers >> checkMembers
26+
where checkUnevenMembers =
27+
if length membersXObjs `mod` 2 == 0
28+
then Right ()
29+
else Left (UnevenMembers membersXObjs)
30+
pairs = pairwise membersXObjs
31+
fields = fst <$> pairs
32+
uniqueFields = nubBy ((==) `on` obj) fields
33+
dups = fields \\ uniqueFields
34+
checkDuplicateMembers =
35+
if length fields == length uniqueFields
36+
then Right ()
37+
else Left (DuplicatedMembers dups)
38+
checkMembers = mapM_ (okXObjForType typeEnv typeVariables . snd) pairs
2539

26-
validateOneCase :: XObj -> a
27-
validateOneCase XObj {} =
28-
error "Type members must be defined using array syntax: [member1 type1 member2 type2 ...]" -- | TODO: How to reach this case?
40+
-- validateOneCase :: XObj -> a
41+
-- validateOneCase XObj {} =
42+
-- error "Type members must be defined using array syntax: [member1 type1 member2 type2 ...]" -- | TODO: How to reach this case?
2943

3044
okXObjForType :: TypeEnv -> [Ty] -> XObj -> Either TypeError ()
3145
okXObjForType typeEnv typeVariables xobj =

0 commit comments

Comments
 (0)