Skip to content

Commit 548b576

Browse files
committed
Update SystemF TypeChecker
Implement Type Application
1 parent 965ea5d commit 548b576

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

src/Language/SystemF/TypeCheck.hs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ typecheck uniqs ctx (Var v) = tcVar uniqs ctx v
1818
typecheck uniqs ctx (Abs n t body) = tcAbs uniqs ctx n t body
1919
typecheck uniqs ctx (App e1 e2) = tcApp uniqs ctx e1 e2
2020
typecheck uniqs ctx (TyAbs t body) = tcTyAbs uniqs ctx t body
21-
typecheck _ _ _ = undefined
21+
typecheck uniqs ctx (TyApp e ty) = tcTyApp uniqs ctx e ty
2222

2323
tcVar :: (Ord n, Eq n, PrettyPrint n)
2424
=> UniqueSupply n
@@ -67,12 +67,48 @@ tcTyAbs :: (Ord n, Eq n, PrettyPrint n)
6767
tcTyAbs uniqs ctx ty body = TyForAll ty <$> typecheck uniqs ctx' body
6868
where ctx' = insert ty (TyVar ty) ctx
6969

70+
tcTyApp :: (Ord n, Eq n, PrettyPrint n)
71+
=> UniqueSupply n
72+
-> Context n (Ty n)
73+
-> SystemFExpr n n
74+
-> Ty n
75+
-> Either String (Ty n)
76+
tcTyApp uniqs ctx (TyAbs t expr) ty = typecheck uniqs ctx expr'
77+
where expr' = sub t ty expr
78+
tcTyApp uniqs ctx expr ty = typecheck uniqs ctx expr
79+
7080
-- Utilities
7181
unique :: UniqueSupply t
7282
-> Either String t
7383
unique (u:_) = return u
7484
unique _ = fail "Unique supply ran out"
7585

86+
sub :: Eq n
87+
=> n
88+
-> Ty n
89+
-> SystemFExpr n n
90+
-> SystemFExpr n n
91+
sub name ty (App e1 e2) = App (sub name ty e1) (sub name ty e2)
92+
sub name ty (Abs n ty' e) = Abs n (subTy name ty ty') (sub name ty e)
93+
sub name ty (TyAbs ty' e) = TyAbs ty' (sub name ty e)
94+
sub name ty (TyApp e ty') = TyApp (sub name ty e) (subTy name ty ty')
95+
sub name ty expr = expr
96+
97+
subTy :: Eq n
98+
=> n
99+
-> Ty n
100+
-> Ty n
101+
-> Ty n
102+
subTy name ty (TyArrow t1 t2)
103+
= TyArrow (subTy name ty t1) (subTy name ty t2)
104+
subTy name ty ty'@(TyVar name')
105+
| name == name' = ty
106+
| otherwise = ty'
107+
subTy name t1 t2@(TyForAll name' t2')
108+
| name == name' = t2
109+
| otherwise = TyForAll name' (subTy name t2 t2')
110+
111+
76112
tyMismatchMsg :: (PrettyPrint t, PrettyPrint t')
77113
=> t
78114
-> t'

test/Language/SystemF/TypeCheckSpec.hs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@ import Data.Map
55

66
import Test.Hspec
77

8+
import Language.Lambda.Util.PrettyPrint
89
import Language.SystemF.Expression
910
import Language.SystemF.TypeCheck
1011

12+
tc :: (Ord n, Eq n, PrettyPrint n)
13+
=> UniqueSupply n
14+
-> [(n, Ty n)]
15+
-> SystemFExpr n n
16+
-> Either String (Ty n)
1117
tc uniqs ctx = typecheck uniqs (fromList ctx)
1218

1319
spec :: Spec
@@ -51,6 +57,19 @@ spec = describe "typecheck" $ do
5157
tc ["A"] [] (TyAbs "X" (Var "x")) `shouldBe` Right (TyForAll "X" (TyVar "A"))
5258

5359
it "typechecks type abstractions with simple abstraction" $
54-
tc [] [] (TyAbs "X" (Abs "x" (TyVar "X") (Var "X"))) `shouldBe`
55-
Right (TyForAll "X" (TyArrow (TyVar "X") (TyVar "X")))
56-
60+
tc [] [] (TyAbs "X" (Abs "x" (TyVar "X") (Var "x")))
61+
`shouldBe` Right (TyForAll "X" (TyArrow (TyVar "X") (TyVar "X")))
62+
63+
it "typechecks type abstractions with application" $
64+
tc [] [("y", TyVar "Y")]
65+
(App (TyApp (TyAbs "X" (Abs "x" (TyVar "X") (Var "x"))) (TyVar "Y"))
66+
(Var "y"))
67+
`shouldBe` Right (TyVar "Y")
68+
69+
it "typechecks simple type applications" $
70+
tc [] [("x", TyVar "A")] (TyApp (TyAbs "X" (Var "x")) (TyVar "X"))
71+
`shouldBe` Right (TyVar "A")
72+
73+
it "typechecks type applications with simple abstraction" $
74+
tc [] [] (TyApp (TyAbs "X" (Abs "x" (TyVar "X") (Var "x"))) (TyVar "Y"))
75+
`shouldBe` Right (TyArrow (TyVar "Y") (TyVar "Y"))

0 commit comments

Comments
 (0)