@@ -16,6 +16,7 @@ import Guid
16data ParseType = VarPT String
16data ParseType = VarPT String
17 | LambdaPT ParseType ParseType
17 | LambdaPT ParseType ParseType
18 | ADTPT String [ParseType]
18 | ADTPT String [ParseType]
19+ | RecordPT [(String,ParseType)]
20listPT t = ADTPT "List" [t]
21listPT t = ADTPT "List" [t]
21tuplePT ts = ADTPT ("Tuple" ++ show (length ts)) ts
22tuplePT ts = ADTPT ("Tuple" ++ show (length ts)) ts
@@ -30,8 +31,14 @@ typeTuple :: IParser ParseType
30typeTuple = do ts <- parens (commaSep typeExpr)
31typeTuple = do ts <- parens (commaSep typeExpr)
31 return $ case ts of { [t] -> t ; _ -> tuplePT ts }
32 return $ case ts of { [t] -> t ; _ -> tuplePT ts }
34+typeRecord :: IParser ParseType
35+typeRecord = fmap RecordPT . brackets . commaSep $ do
37+ whitespace >> string "::" >> whitespace
33typeUnambiguous :: IParser ParseType
40typeUnambiguous :: IParser ParseType
34−typeUnambiguous = typeList <|> typeTuple
41+typeUnambiguous = typeList <|> typeTuple <|> typeRecord
36typeSimple :: IParser ParseType
43typeSimple :: IParser ParseType
37typeSimple = dealias <$> var
44typeSimple = dealias <$> var
@@ -80,6 +87,8 @@ toDatatype name args tcs = Datatype name [1..n] <$> mapM toC tcs
80 Just v -> Right v
87 Just v -> Right v
81 Nothing -> Left $ msg x
88 Nothing -> Left $ msg x
82 | otherwise = return $ ADT x []
89 | otherwise = return $ ADT x []
90+ toT (RecordPT fs) = do fs' <- mapM (\(x,pt) -> (,) x <$> toT pt) fs
91+ return (RecordT (recordT fs') EmptyRecord)
83 msg x = "Type variable '" ++ x ++
92 msg x = "Type variable '" ++ x ++
84 "' is unbound in type constructor '" ++ name ++ "'."
93 "' is unbound in type constructor '" ++ name ++ "'."