adt support in type inference

This commit is contained in:
crumbtoo
2024-04-05 12:28:58 -06:00
parent c147b6f3db
commit 5511d70e26
3 changed files with 50 additions and 8 deletions

View File

@@ -101,7 +101,8 @@ For the time being, I just disabled the memoisation. This is very, very bad.
** TODO [#A] ~case~ inference :feature: ** TODO [#A] ~case~ inference :feature:
** TODO [#A] ADT support in Rlp/HindleyMilner.hs :feature: ** DONE [#A] ADT support in Rlp/HindleyMilner.hs :feature:
CLOSED: [2024-04-05 Fri 12:28]
** DONE whole-program inference (wrap top-level in a ~letrec~) :feature: ** DONE whole-program inference (wrap top-level in a ~letrec~) :feature:
CLOSED: [2024-04-04 Thu 12:42] CLOSED: [2024-04-04 Thu 12:42]

View File

@@ -2,7 +2,7 @@
module Rlp.AltSyntax module Rlp.AltSyntax
( (
-- * AST -- * AST
Program(..), Decl(..), ExprF(..), Pat(..) Program(..), Decl(..), ExprF(..), Pat(..), pattern ConP'
, RlpExprF, RlpExpr, Binding(..), Alter(..) , RlpExprF, RlpExpr, Binding(..), Alter(..)
, RlpExpr', RlpExprF', AnnotatedRlpExpr', Type' , RlpExpr', RlpExprF', AnnotatedRlpExpr', Type'
, DataCon(..), Type(..), Kind , DataCon(..), Type(..), Kind
@@ -18,7 +18,7 @@ module Rlp.AltSyntax
-- * Optics -- * Optics
, programDecls , programDecls
, _VarP, _FunB, _VarB , _VarP, _FunB, _VarB
, _TySigD, _FunD , _TySigD, _FunD, _DataD
, _LetEF , _LetEF
, Core.applicants1, Core.arrowStops , Core.applicants1, Core.arrowStops
@@ -141,6 +141,20 @@ data Pat b = VarP b
| AppP (Pat b) (Pat b) | AppP (Pat b) (Pat b)
deriving (Eq, Show, Generic, Generic1) deriving (Eq, Show, Generic, Generic1)
conList :: Prism' (Pat b) (b, [Pat b])
conList = prism' up down where
up (b,as) = foldl AppP (ConP b) as
down (ConP b) = Just (b, [])
down (AppP (ConP b) as) = Just (b, go as)
down _ = Nothing
go (AppP f x) = f : go x
go p = [p]
pattern ConP' :: b -> [Pat b] -> Pat b
pattern ConP' c as <- (preview conList -> Just (c,as))
where ConP' c as = review conList (c,as)
deriveShow1 ''Alter deriveShow1 ''Alter
deriveShow1 ''Binding deriveShow1 ''Binding
deriveShow1 ''ExprF deriveShow1 ''ExprF

View File

@@ -136,6 +136,11 @@ gather (InR (LetEF Rec (withoutPatterns -> bs) (te,je))) = do
elimRecBind (x,(tx,_)) j = elim x tx j elimRecBind (x,(tx,_)) j = elim x tx j
elimBind (x,(tx,_)) j = elimGenerally x tx j elimBind (x,(tx,_)) j = elimGenerally x tx j
gather (InR (CaseEF (te,je) [Alter (ConP' n []) (ta,ja)])) = do
tc <- freshTv
let j = equal te tc <> je <> assume n tc <> ja
pure (ta,j)
forBinds :: (PsName -> Type' -> Judgement -> Judgement) forBinds :: (PsName -> Type' -> Judgement -> Judgement)
-> [(PsName, Type')] -> Judgement -> Judgement -> [(PsName, Type')] -> Judgement -> Judgement
forBinds f bs j = foldr (uncurry f) j bs forBinds f bs j = foldr (uncurry f) j bs
@@ -165,6 +170,9 @@ unify (c:cs) = case c of
Equality (s :-> t) (s' :-> t') Equality (s :-> t) (s' :-> t')
-> unify (Equality s s' : Equality t t' : cs) -> unify (Equality s s' : Equality t t' : cs)
Equality (AppT s t) (AppT s' t')
-> unify (Equality s s' : Equality t t' : cs)
ImplicitInstance m s t ImplicitInstance m s t
| null $ (freeTvs t `S.difference` freeTvs m) | null $ (freeTvs t `S.difference` freeTvs m)
`S.intersection` activeTvs cs `S.intersection` activeTvs cs
@@ -198,11 +206,19 @@ generalise m t = foldr ForallT t as
occurs :: (HasTypes a) => Name -> a -> Bool occurs :: (HasTypes a) => Name -> a -> Bool
occurs x t = x `elem` freeTvs t occurs x t = x `elem` freeTvs t
elimGlobalBinds :: [(Name, Scheme)] -> Cofree RlpExprF' (Type', Judgement)
-> Cofree RlpExprF' (Type', Judgement)
elimGlobalBinds bs = traversed . _2 %~ forBinds f bs where
f n t@(ForallT _ _) = elimGenerally n t
f n t = elim n t
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
annotate :: (Unique :> es) annotate :: (Unique :> es)
=> RlpExpr' -> Eff es (Cofree RlpExprF' (Type', Judgement)) => RlpExpr' -> Eff es (Cofree RlpExprF' (Type', Judgement))
annotate = dendroscribeM (gather . fmap extract) annotate = fmap (elimGlobalBinds [ ("Just", ForallT "a" $ VarT "a" :-> ConT "Maybe" `AppT` VarT "a")
, ("isJust", ForallT "a" $ ConT "Maybe" `AppT` VarT "a" :-> ConT "Bool")])
. dendroscribeM (gather . fmap extract)
orderConstraints :: [Constraint] -> [Constraint] orderConstraints :: [Constraint] -> [Constraint]
orderConstraints cs = a <> b orderConstraints cs = a <> b
@@ -266,21 +282,32 @@ annotateDefs :: (Unique :> es)
(Cofree RlpExprF' (Type', Judgement))) (Cofree RlpExprF' (Type', Judgement)))
annotateDefs = traverseOf (programDefs . _2) annotate annotateDefs = traverseOf (programDefs . _2) annotate
extractDefs :: Program PsName (Cofree RlpExprF' (Type', Judgement))
-> [(Name, Type')]
extractDefs p = p ^.. programDefs & each . _2 %~ fst . extract
extractCons :: Program PsName (Cofree RlpExprF' (Type', Judgement))
-> [(Name, Type')]
extractCons = foldMapOf (programDecls . each . _DataD) \(n,as,cs) ->
let root = foldl AppT (ConT n) (VarT <$> as)
in cs & fmap \ (DataCon cn cas) -> (cn, foldr (:->) root cas)
annotateProg :: (Unique :> es) annotateProg :: (Unique :> es)
=> Program PsName RlpExpr' => Program PsName RlpExpr'
-> Eff es (Program PsName -> Eff es (Program PsName
(Cofree RlpExprF' (Type', Judgement))) (Cofree RlpExprF' (Type', Judgement)))
annotateProg p = do annotateProg p = do
p' <- annotateDefs p p' <- annotateDefs p
let bs = p' ^.. programDefs & each . _2 %~ (fst . extract) let bs = extractCons p' ++ extractDefs p'
p'' = p' & programDefs . _2 . traversed . _2 p'' = p' & programDefs . _2 . traversed . _2
%~ forBinds elimGenerally bs %~ forBinds elimGenerally bs
pure p'' pure p''
programDefs :: Traversal (Program b a) (Program b a') (b, a) (b, a') programDefs :: Traversal (Program b a) (Program b a') (b, a) (b, a')
programDefs k (Program ds) = Program <$> go k ds where programDefs k (Program ds) = Program <$> traverse go ds where
go k [] = pure [] go (FunD n as e) = refun as (k (n,e))
go k (FunD n as e : ds) = (:) <$> refun as (k (n,e)) <*> go k ds go (DataD n as cs) = pure $ DataD n as cs
go (TySigD n ts) = pure $ TySigD n ts
refun as kne = uncurry (\a b -> FunD a as b) <$> kne refun as kne = uncurry (\a b -> FunD a as b) <$> kne
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------