Skip to content

Commit 551133c

Browse files
authored
Support type signatures (#85)
1 parent d8a8ba2 commit 551133c

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

examples/35-type-sigs.hell

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
data Foo = Foo { bar, mu :: Int }
2+
main :: IO () =
3+
Main.foo
4+
5+
foo = do
6+
let bar = 123
7+
let mu = 666
8+
let r = Main.Foo{bar,mu}
9+
IO.print $ (Record.get @"bar" r :: Int)

src/Hell.hs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,18 @@ parseModule (HSE.Module _ Nothing [] [] decls) = do
208208
parseDecl (HSE.PatBind _ (HSE.PVar _ (HSE.Ident _ string)) (HSE.UnGuardedRhs _ exp') Nothing) =
209209
pure ([(string, exp')], types)
210210
where types = []
211+
parseDecl (HSE.PatBind _ (HSE.PatTypeSig l (HSE.PVar _ (HSE.Ident _ string))
212+
typ)
213+
(HSE.UnGuardedRhs _ exp') Nothing) =
214+
pure ([(string, HSE.ExpTypeSig l exp' typ)], types)
215+
where types = []
211216
parseDecl (HSE.DataDecl _ HSE.DataType {} Nothing (HSE.DHead _ name) [qualConDecl] []) =
212217
do (termName,termExpr,typeName,typ) <- parseDataDecl name qualConDecl
213218
pure ([(termName,termExpr)], [(typeName,typ)])
214219
parseDecl (HSE.DataDecl _ HSE.DataType {} Nothing (HSE.DHead _ name) qualConDecls []) =
215220
do (terms, tyname, typ) <- parseSumDecl name qualConDecls
216221
pure (terms, [(tyname,typ)])
217-
parseDecl _ = fail "Can't parse that!"
222+
parseDecl d = fail $ "Can't parse that! " ++ show d
218223
parseModule _ = fail "Module headers aren't supported."
219224

220225
-- data Value = Text Text | Number Int
@@ -452,6 +457,7 @@ data UTerm t
452457
= UVar HSE.SrcSpanInfo t String
453458
| ULam HSE.SrcSpanInfo t Binding (Maybe SomeStarType) (UTerm t)
454459
| UApp HSE.SrcSpanInfo t (UTerm t) (UTerm t)
460+
| USig HSE.SrcSpanInfo t (UTerm t) SomeStarType
455461
| -- IRep below: The variables are poly types, they aren't metavars,
456462
-- and need to be instantiated.
457463
UForall Prim HSE.SrcSpanInfo t [SomeTypeRep] Forall [TH.Uniq] (IRep TH.Uniq) [t]
@@ -462,6 +468,7 @@ typeOf = \case
462468
UVar _ t _ -> t
463469
ULam _ t _ _ _ -> t
464470
UApp _ t _ _ -> t
471+
USig _ t _ _ -> t
465472
UForall _ _ t _ _ _ _ _ -> t
466473

467474
data Binding = Singleton String | Tuple [String]
@@ -508,6 +515,9 @@ data Prim = LitP (HSE.Literal HSE.SrcSpanInfo) | NameP String | UnitP
508515

509516
data SomeStarType = forall (a :: Type). SomeStarType (TypeRep a)
510517

518+
instance Pretty SomeStarType where
519+
pretty (SomeStarType a) = pretty a
520+
511521
deriving instance Show SomeStarType
512522

513523
instance Eq SomeStarType where
@@ -555,6 +565,14 @@ check = tc
555565

556566
-- Type check a term given an environment of names.
557567
tc :: (UTerm SomeTypeRep) -> TyEnv g -> Either TypeCheckError (Typed (Term g))
568+
tc (USig _l _ e (SomeStarType someStarType)) env = do
569+
case tc e env of
570+
Left err -> Left err
571+
Right typed'@(Typed ty _)
572+
| Just {} <- Type.eqTypeRep ty someStarType ->
573+
pure typed'
574+
| otherwise ->
575+
Left TypeCheckMismatch
558576
tc (UVar _ _ v) env = do
559577
Typed ty v' <- lookupVar v env
560578
pure $ Typed ty (Var v')
@@ -747,6 +765,10 @@ desugarExp ::
747765
desugarExp userDefinedTypeAliases globals = go mempty
748766
where
749767
go scope = \case
768+
HSE.ExpTypeSig l e ty -> do
769+
e' <- go scope e
770+
ty' <- desugarStarType userDefinedTypeAliases ty
771+
pure $ USig l () e' ty'
750772
HSE.Case l e alts -> do
751773
e' <- desugarCase l e alts
752774
go scope e'
@@ -1968,6 +1990,10 @@ elaborate = fmap getEqualities . flip runStateT empty . flip runReaderT mempty .
19681990
getEqualities (term, Elaborate {equalities}) = (term, equalities)
19691991
go :: UTerm () -> ReaderT (Map String (IRep IMetaVar)) (StateT Elaborate (Either ElaborateError)) (UTerm (IRep IMetaVar))
19701992
go = \case
1993+
USig l () e ty -> do
1994+
e' <- go e
1995+
equal l (typeOf e') (fromSomeStarType ty)
1996+
pure $ e'
19711997
UVar l () string -> do
19721998
env <- ask
19731999
ty <- case Map.lookup string env of
@@ -2271,6 +2297,7 @@ instance Pretty (UTerm t) where
22712297
pretty = \case
22722298
UVar _ _ v -> pretty v
22732299
UApp _ _ f x -> "(" <> pretty f <> " " <> pretty x <> ")"
2300+
USig _ _ f s -> "(" <> pretty f <> " :: " <> pretty s <> ")"
22742301
UForall prim _ _ _ _ _ _ _ -> pretty prim
22752302
ULam _ _ binding _ t ->
22762303
"(\\" <> pretty binding <> " -> " <> pretty t <> ")"

0 commit comments

Comments
 (0)