letrec
This commit is contained in:
@@ -3,6 +3,7 @@ Module : Core.HindleyMilner
|
|||||||
Description : Hindley-Milner type system
|
Description : Hindley-Milner type system
|
||||||
-}
|
-}
|
||||||
{-# LANGUAGE LambdaCase #-}
|
{-# LANGUAGE LambdaCase #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
module Core.HindleyMilner
|
module Core.HindleyMilner
|
||||||
( Context'
|
( Context'
|
||||||
, infer
|
, infer
|
||||||
@@ -16,12 +17,13 @@ module Core.HindleyMilner
|
|||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
import Lens.Micro
|
import Lens.Micro
|
||||||
import Lens.Micro.Mtl
|
import Lens.Micro.Mtl
|
||||||
|
import Lens.Micro.Platform
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
import Data.HashMap.Strict qualified as H
|
import Data.HashMap.Strict qualified as H
|
||||||
import Data.Foldable (traverse_)
|
import Data.Foldable (traverse_)
|
||||||
import Compiler.RLPC
|
import Compiler.RLPC
|
||||||
import Control.Monad (foldM, void)
|
import Control.Monad (foldM, void, forM)
|
||||||
import Control.Monad.Errorful (Errorful, addFatal)
|
import Control.Monad.Errorful (Errorful, addFatal)
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
import Control.Monad.Utils (mapAccumLM)
|
import Control.Monad.Utils (mapAccumLM)
|
||||||
@@ -152,8 +154,28 @@ gather = \g e -> runStateT (go g e) ([],0) <&> \ (t,(cs,_)) -> (t,cs) where
|
|||||||
Let NonRec bs e -> do
|
Let NonRec bs e -> do
|
||||||
g' <- buildLetContext g bs
|
g' <- buildLetContext g bs
|
||||||
go g' e
|
go g' e
|
||||||
|
Let Rec bs e -> do
|
||||||
|
g' <- buildLetrecContext g bs
|
||||||
|
go g' e
|
||||||
|
|
||||||
-- TODO letrec, lambda, case
|
-- TODO letrec, lambda, case
|
||||||
|
|
||||||
|
buildLetrecContext :: Context' -> [Binding']
|
||||||
|
-> StateT ([Constraint], Int) HMError Context'
|
||||||
|
buildLetrecContext g bs = do
|
||||||
|
let f ag (k := _) = do
|
||||||
|
n <- uniqueVar
|
||||||
|
pure ((k,n) : ag)
|
||||||
|
rg <- foldM f g bs
|
||||||
|
let k ag (k := v) = do
|
||||||
|
t <- go rg v
|
||||||
|
pure ((k,t) : ag)
|
||||||
|
foldM k g bs
|
||||||
|
|
||||||
|
-- | augment a context with the inferred types of each binder. the returned
|
||||||
|
-- context is linearly accumulated, meaning that the context used to infer each binder
|
||||||
|
-- will include the inferred types of all previous binder
|
||||||
|
|
||||||
buildLetContext :: Context' -> [Binding']
|
buildLetContext :: Context' -> [Binding']
|
||||||
-> StateT ([Constraint], Int) HMError Context'
|
-> StateT ([Constraint], Int) HMError Context'
|
||||||
buildLetContext = foldM k where
|
buildLetContext = foldM k where
|
||||||
@@ -230,3 +252,17 @@ subst x t (TyVar y) | x == y = t
|
|||||||
subst x t (a :-> b) = subst x t a :-> subst x t b
|
subst x t (a :-> b) = subst x t a :-> subst x t b
|
||||||
subst _ _ e = e
|
subst _ _ e = e
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
demoContext :: Context'
|
||||||
|
demoContext =
|
||||||
|
[ ("fix", (TyVar "a" :-> TyVar "a") :-> TyVar "a")
|
||||||
|
, ("add", TyInt :-> TyInt :-> TyInt)
|
||||||
|
]
|
||||||
|
|
||||||
|
pprintType :: Type -> String
|
||||||
|
pprintType (s :-> t) = "(" <> pprintType s <> " -> " <> pprintType t <> ")"
|
||||||
|
pprintType TyFun = "(->)"
|
||||||
|
pprintType (TyVar x) = x ^. unpacked
|
||||||
|
pprintType (TyCon t) = t ^. unpacked
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user