@@ -17,6 +17,19 @@ import qualified AST.Type as T
17import qualified AST.Variable as Var
17import qualified AST.Variable as Var
22+type Type = TermN Variable
24+type Variable = UF.Point Descriptor
26+type TypeConstraint = Constraint Type Variable
28+type TypeScheme = Scheme Type Variable
20data Term1 a
33data Term1 a
21 = App1 a a
34 = App1 a a
22 | Fun1 a a
35 | Fun1 a a
@@ -26,82 +39,26 @@ data Term1 a
28data TermN a
41data TermN a
29− = VarN (Maybe Var.Canonical) a
42+ = VarN (Maybe Var.Canonical) a
30 | TermN (Maybe Var.Canonical) (Term1 (TermN a))
43 | TermN (Maybe Var.Canonical) (Term1 (TermN a))
33varN :: a -> TermN a
46varN :: a -> TermN a
34−varN = VarN Nothing
48+ VarN Nothing
37termN :: (Term1 (TermN a)) -> TermN a
51termN :: (Term1 (TermN a)) -> TermN a
38−termN = TermN Nothing
53+ TermN Nothing
41record :: Map.Map String [TermN a] -> TermN a -> TermN a
56record :: Map.Map String [TermN a] -> TermN a -> TermN a
42−record fs rec = termN (Record1 fs rec)
58+ termN (Record1 fs rec)
45−type Type = TermN Variable
48−type Variable = UF.Point Descriptor
51−type SchemeName = String
54−type TypeName = Var.Canonical
57−type Constraint a b = Located (BasicConstraint a b)
60−data BasicConstraint a b
64− | CAnd [Constraint a b]
65− | CLet [Scheme a b] (Constraint a b)
66− | CInstance SchemeName a
69−data Scheme a b = Scheme
70− { rigidQuantifiers :: [b]
71− , flexibleQuantifiers :: [b]
72− , constraint :: Constraint a b
73− , header :: Map.Map String a
77−type TypeConstraint = Constraint Type Variable
79−type TypeScheme = Scheme Type Variable
82−monoscheme :: Map.Map String a -> Scheme a b
83−monoscheme headers = Scheme [] [] (noneNoDocs CTrue) headers
88−(/\) :: Constraint a b -> Constraint a b -> Constraint a b
89−a@(A _ c1) /\ b@(A _ c2) =
93− _ -> mergeOldDocs a b (CAnd [a,b])
98−(==>) :: Type -> Type -> Type
99−a ==> b = termN (Fun1 a b)
102−(<|) :: TermN a -> TermN a -> TermN a
103−f <| a = termN (App1 f a)
106data Descriptor = Descriptor
63data Descriptor = Descriptor
107 { structure :: Maybe (Term1 Variable)
64 { structure :: Maybe (Term1 Variable)
@@ -113,23 +70,18 @@ data Descriptor = Descriptor
113 , alias :: Maybe Var.Canonical
70 , alias :: Maybe Var.Canonical
117noRank :: Int
73noRank :: Int
118noRank = -1
74noRank = -1
121outermostRank :: Int
76outermostRank :: Int
122outermostRank = 0
77outermostRank = 0
125noMark :: Int
79noMark :: Int
126noMark = 0
80noMark = 0
129initialMark :: Int
82initialMark :: Int
130initialMark = 1
83initialMark = 1
135 | Flexible
87 | Flexible
@@ -137,7 +89,6 @@ data Flex
137 | Is SuperType
89 | Is SuperType
138 deriving (Eq)
90 deriving (Eq)
141data SuperType
92data SuperType
143 | Comparable
94 | Comparable
@@ -145,6 +96,47 @@ data SuperType
145 deriving (Eq)
96 deriving (Eq)
101+type Constraint a b =
102+ Located (BasicConstraint a b)
104+data BasicConstraint a b
108+ | CAnd [Constraint a b]
109+ | CLet [Scheme a b] (Constraint a b)
110+ | CInstance SchemeName a
112+type SchemeName = String
114+type TypeName = Var.Canonical
116+data Scheme a b = Scheme
117+ { rigidQuantifiers :: [b]
118+ , flexibleQuantifiers :: [b]
119+ , constraint :: Constraint a b
120+ , header :: Map.Map String a
128+(==>) :: Type -> Type -> Type
133+(<|) :: TermN a -> TermN a -> TermN a
148namedVar :: Flex -> Var.Canonical -> IO Variable
140namedVar :: Flex -> Var.Canonical -> IO Variable
149namedVar flex name = UF.fresh $ Descriptor
141namedVar flex name = UF.fresh $ Descriptor
150 { structure = Nothing
142 { structure = Nothing
@@ -169,6 +161,23 @@ variable flex = UF.fresh $ Descriptor
164+-- CONSTRAINT HELPERS
166+monoscheme :: Map.Map String a -> Scheme a b
168+ Scheme [] [] (noneNoDocs CTrue) headers
173+(/\) :: Constraint a b -> Constraint a b -> Constraint a b
174+(/\) a@(A _ c1) b@(A _ c2) =
178+ _ -> mergeOldDocs a b (CAnd [a,b])
172-- ex qs constraint == exists qs. constraint
181-- ex qs constraint == exists qs. constraint
173ex :: [Variable] -> TypeConstraint -> TypeConstraint
182ex :: [Variable] -> TypeConstraint -> TypeConstraint
174ex fqs constraint@(A ann _) =
183ex fqs constraint@(A ann _) =
@@ -213,36 +222,51 @@ instance PrettyType a => PrettyType (Term1 a) where
213 parensIf needed (px <+> pretty App x)
222 parensIf needed (px <+> pretty App x)
215 px = prty f
224 px = prty f
216− needed = case when of
226+ case when of
217− App -> True
227+ App -> True
218− _ -> False
228+ _ -> False
220 Fun1 arg body ->
230 Fun1 arg body ->
221 parensIf needed (pretty Fn arg <+> P.text "->" <+> prty body)
231 parensIf needed (pretty Fn arg <+> P.text "->" <+> prty body)
223− needed = case when of
234+ case when of
224− Never -> False
235+ Never -> False
225− _ -> True
236+ _ -> True
227− Var1 x -> prty x
238+ Var1 x ->
229− EmptyRecord1 -> P.braces P.empty
242+ P.braces P.empty
231 Record1 fields ext ->
244 Record1 fields ext ->
232 P.braces (extend <+> commaSep prettyFields)
245 P.braces (extend <+> commaSep prettyFields)
234 prettyExt = prty ext
247 prettyExt = prty ext
235− extend | P.render prettyExt == "{}" = P.empty
250+ | P.render prettyExt == "{}" =
236− | otherwise = prettyExt <+> P.text "|"
253+ prettyExt <+> P.text "|"
237− mkPretty f t = P.text f <+> P.text ":" <+> prty t
256+ P.text f <+> P.text ":" <+> prty t
238− prettyFields = concatMap (\(f,ts) -> map (mkPretty f) ts) (Map.toList fields)
259+ concatMap (\(f,ts) -> map (mkPretty f) ts) (Map.toList fields)
241instance PrettyType a => PrettyType (TermN a) where
262instance PrettyType a => PrettyType (TermN a) where
242 pretty when term =
263 pretty when term =
243 case term of
264 case term of
244− VarN alias x -> either alias (pretty when x)
266+ either alias (pretty when x)
245− TermN alias t1 -> either alias (pretty when t1)
269+ either alias (pretty when t1)
247 either maybeAlias doc =
271 either maybeAlias doc =
248 case maybeAlias of
272 case maybeAlias of
@@ -251,16 +275,20 @@ instance PrettyType a => PrettyType (TermN a) where
253instance PrettyType Descriptor where
277instance PrettyType Descriptor where
254− pretty when desc = do
278+ pretty when desc =
255 case (alias desc, structure desc, name desc) of
279 case (alias desc, structure desc, name desc) of
280+ (Just name, _, _) ->
256− (Just name, _, _) -> PP.pretty name
281+ PP.pretty name
283+ (_, Just term, _) ->
257− (_, Just term, _) -> pretty when term
284+ pretty when term
258 (_, _, Just name)
286 (_, _, Just name)
259 | Var.isTuple name ->
287 | Var.isTuple name ->
260 P.parens . P.text $ replicate (read (drop 6 (Var.toString name)) - 1) ','
288 P.parens . P.text $ replicate (read (drop 6 (Var.toString name)) - 1) ','
261 | otherwise ->
289 | otherwise ->
262 P.text (Var.toString name)
290 P.text (Var.toString name)
264 _ -> P.text "?"
292 _ -> P.text "?"
@@ -320,20 +348,27 @@ instance (PrettyType a, PrettyType b) => PrettyType (Scheme a b) where
322extraPretty :: (PrettyType t, Crawl t) => t -> IO Doc
350extraPretty :: (PrettyType t, Crawl t) => t -> IO Doc
323−extraPretty t = pretty Never <$> addNames t
352+ pretty Never <$> addNames t
326-- ADDING NAMES TO TYPES
355-- ADDING NAMES TO TYPES
328addNames :: (Crawl t) => t -> IO t
357addNames :: (Crawl t) => t -> IO t
329−addNames value = do
358+addNames value =
330− (rawVars, _, _, _) <- execStateT (crawl getNames value) ([], 0, 0, 0)
359+ do (rawVars, _, _, _) <- execStateT (crawl getNames value) ([], 0, 0, 0)
331− let vars = map head . List.group $ List.sort rawVars
361+ let vars = map head . List.group $ List.sort rawVars
332− suffix s = map (++s) (map (:[]) ['a'..'z'])
363+ let suffix s = map (++s) (map (:[]) ['a'..'z'])
333− allVars = concatMap suffix $ ["","'","_"] ++ map show [ (0 :: Int) .. ]
365+ let allVars = concatMap suffix $ ["","'","_"] ++ map show [ (0 :: Int) .. ]
334− okayVars = filter (`notElem` vars) allVars
367+ let okayVars = filter (`notElem` vars) allVars
335− runStateT (crawl rename value) (okayVars, 0, 0, 0)
369+ runStateT (crawl rename value) (okayVars, 0, 0, 0)
336− return value
371+ return value
338 getNames desc state@(vars, a, b, c) =
373 getNames desc state@(vars, a, b, c) =
339 let name' = name desc in
374 let name' = name desc in
@@ -368,23 +403,25 @@ class Crawl t where
370instance Crawl e => Crawl (Annotated a e) where
405instance Crawl e => Crawl (Annotated a e) where
371− crawl nextState (A ann e) = A ann <$> crawl nextState e
406+ crawl nextState (A ann e) =
407+ A ann <$> crawl nextState e
374instance (Crawl t, Crawl v) => Crawl (BasicConstraint t v) where
410instance (Crawl t, Crawl v) => Crawl (BasicConstraint t v) where
375− crawl nextState constraint =
411+ crawl nextState constraint =
376 let rnm = crawl nextState in
412 let rnm = crawl nextState in
377 case constraint of
413 case constraint of
378 CTrue -> return CTrue
414 CTrue -> return CTrue
379 CSaveEnv -> return CSaveEnv
415 CSaveEnv -> return CSaveEnv
380 CEqual a b -> CEqual <$> rnm a <*> rnm b
416 CEqual a b -> CEqual <$> rnm a <*> rnm b
381 CAnd cs -> CAnd <$> crawl nextState cs
417 CAnd cs -> CAnd <$> crawl nextState cs
382− CLet schemes c -> CLet <$> crawl nextState schemes <*> crawl nextState c
418+ CLet schemes c -> CLet <$> crawl nextState schemes <*> crawl nextState c
383 CInstance name tipe -> CInstance name <$> rnm tipe
419 CInstance name tipe -> CInstance name <$> rnm tipe
386instance Crawl a => Crawl [a] where
422instance Crawl a => Crawl [a] where
423+ crawl nextState list =
387− crawl nextState list = mapM (crawl nextState) list
424+ mapM (crawl nextState) list
390instance (Crawl t, Crawl v) => Crawl (Scheme t v) where
427instance (Crawl t, Crawl v) => Crawl (Scheme t v) where
@@ -410,14 +447,24 @@ instance Crawl t => Crawl (TermN t) where
411instance Crawl t => Crawl (Term1 t) where
448instance Crawl t => Crawl (Term1 t) where
412 crawl nextState term =
449 crawl nextState term =
413− let rnm = crawl nextState in
450+ let rnm = crawl nextState in
414− case term of
451+ case term of
415− App1 a b -> App1 <$> rnm a <*> rnm b
453+ App1 <$> rnm a <*> rnm b
416− Fun1 a b -> Fun1 <$> rnm a <*> rnm b
456+ Fun1 <$> rnm a <*> rnm b
417− Var1 a -> Var1 <$> rnm a
459+ Var1 <$> rnm a
418− EmptyRecord1 -> return EmptyRecord1
462+ return EmptyRecord1
419 Record1 fields ext ->
464 Record1 fields ext ->
420− Record1 <$> traverse (mapM rnm) fields <*> rnm ext
466+ <$> traverse (mapM rnm) fields
423instance Crawl a => Crawl (UF.Point a) where
470instance Crawl a => Crawl (UF.Point a) where
@@ -436,7 +483,7 @@ instance Crawl Descriptor where
436 put state'
483 put state'
437 return $ desc { name = name', structure = structure' }
484 return $ desc { name = name', structure = structure' }
440toSrcType :: Variable -> IO T.CanonicalType
487toSrcType :: Variable -> IO T.CanonicalType
441toSrcType var =
488toSrcType var =
442 go =<< addNames var
489 go =<< addNames var
@@ -446,40 +493,53 @@ toSrcType var =
446 srcType <- maybe (backupSrcType desc) termToSrcType (structure desc)
493 srcType <- maybe (backupSrcType desc) termToSrcType (structure desc)
447 return $ maybe srcType (\name -> T.Aliased name srcType) (alias desc)
494 return $ maybe srcType (\name -> T.Aliased name srcType) (alias desc)
449− backupSrcType desc =
496+ backupSrcType :: Descriptor -> IO T.CanonicalType
497+ backupSrcType desc =
450 case name desc of
498 case name desc of
451 Just v@(Var.Canonical _ x@(c:_))
499 Just v@(Var.Canonical _ x@(c:_))
452− | Char.isLower c -> return (T.Var x)
500+ | Char.isLower c ->
453− | otherwise -> return $ T.Type v
503+ return $ T.Type v
455− _ -> error $ concat
507+ concat
456− [ "Problem converting the following type "
508+ [ "Problem converting the following type "
457− , "from a type-checker type to a source-syntax type:"
509+ , "from a type-checker type to a source-syntax type:"
458− , P.render (pretty Never var) ]
510+ , P.render (pretty Never var)
513+ termToSrcType :: Term1 Variable -> IO T.CanonicalType
460 termToSrcType term =
514 termToSrcType term =
461 case term of
515 case term of
462− App1 a b -> do
516+ App1 a b ->
463− a' <- go a
517+ do a' <- go a
464− b' <- go b
518+ b' <- go b
465− case a' of
519+ case a' of
466− T.App f args -> return $ T.App f (args ++ [b'])
521+ return $ T.App f (args ++ [b'])
467− _ -> return $ T.App a' [b']
523+ return $ T.App a' [b']
469− Fun1 a b -> T.Lambda <$> go a <*> go b
526+ T.Lambda <$> go a <*> go b
471− Var1 a -> go a
528+ Var1 a ->
473− EmptyRecord1 -> return $ T.Record [] Nothing
532+ return $ T.Record [] Nothing
475− Record1 tfields extension -> do
534+ Record1 tfields extension ->
476− fields' <- traverse (mapM go) tfields
535+ do fields' <- traverse (mapM go) tfields
477− let fields = concat [ map ((,) name) ts | (name,ts) <- Map.toList fields' ]
536+ let fields = concat [ map ((,) name) ts | (name,ts) <- Map.toList fields' ]
478− ext' <- dealias <$> go extension
537+ ext' <- dealias <$> go extension
479− return $ case ext' of
539+ case ext' of
480− T.Record fs ext -> T.Record (fs ++ fields) ext
540+ T.Record fs ext -> T.Record (fs ++ fields) ext
481− T.Var _ -> T.Record fields (Just ext')
541+ T.Var _ -> T.Record fields (Just ext')
482− _ -> error "Used toSrcType on a type that is not well-formed"
542+ _ -> error "Used toSrcType on a type that is not well-formed"
484 dealias :: T.CanonicalType -> T.CanonicalType
544 dealias :: T.CanonicalType -> T.CanonicalType
485 dealias t =
545 dealias t =
@@ -488,11 +548,15 @@ toSrcType var =
491−data AppStructure = List Variable | Tuple [Variable] | Other
551+data AppStructure
494collectApps :: Variable -> IO AppStructure
557collectApps :: Variable -> IO AppStructure
495−collectApps var = go [] var
558+collectApps var =
497 go vars var = do
561 go vars var = do
498 desc <- UF.descriptor var
562 desc <- UF.descriptor var