From: Mart Lubbers Date: Fri, 8 Mar 2019 12:48:35 +0000 (+0100) Subject: letrec X-Git-Url: https://git.martlubbers.net/?a=commitdiff_plain;h=fab20f52753ebb688a5fefb2b1d92f45bec93fb7;p=minfp.git letrec --- diff --git a/ast.icl b/ast.icl index 9280dd3..1a4d7c1 100644 --- a/ast.icl +++ b/ast.icl @@ -16,7 +16,7 @@ instance toString Expression where toString (Let ns r) = concat [ "let\n" , concat [concat ["\t", toString n, " = ", toString v, "\n"]\\(n, v)<-ns] - , " in\n", toString r] + , "in\n", toString r] toString _ = abort "toString Expression not implemented" instance toString Value where diff --git a/check.icl b/check.icl index b0e078d..abff97a 100644 --- a/check.icl +++ b/check.icl @@ -40,12 +40,12 @@ preamble :: TypeEnv preamble = fromList [(['_if'], Forall [['_ift']] $ TBool --> TVar ['_ift'] --> TVar ['_ift'] --> TVar ['_ift']) - ,(['_eq'], Forall [['_eq']] $ TInt --> TInt --> TBool) + ,(['_eq'], Forall [['_eq']] $ TInt --> TInt --> TBool) ,(['_mul'], Forall [['_mul']] $ TInt --> TInt --> TInt) ,(['_add'], Forall [['_add']] $ TInt --> TInt --> TInt) ,(['_sub'], Forall [['_sub']] $ TInt --> TInt --> TInt) ] -:: Subst :== Map [Char] Type +:: Subst :== Map [Char] Type :: Infer a :== StateT [Int] (Either [String]) a runInfer :: (Infer (Subst, Type)) -> Either [String] Scheme @@ -55,7 +55,7 @@ runInfer i = uncurry ((o) (generalize newMap) o apply) fresh :: Infer Type fresh = getState >>= \[s:ss]->put ss >>| pure (TVar (['v':[c\\c<-:toString s]])) -(oo) infixr 9 :: Subst Subst -> Subst +(oo) infixl 9 :: Subst Subst -> Subst (oo) s1 s2 = 'Data.Map'.union (apply s1 <$> s2) s1 class Substitutable a where @@ -125,12 +125,13 @@ infer env (Lambda x b) = fresh >>= \tv-> infer ('Data.Map'.put x (Forall [] tv) env) b >>= \(s1, t1)->pure (s1, apply s1 tv --> t1) -//infer env (Let x e1 e2) +//infer env (Let [(x, e1)] e2) // = infer env e1 // >>= \(s1, t1)->infer ('Data.Map'.put x (generalize (apply s1 env) t1) env) e2 // >>= \(s2, t2)->pure (s1 oo s2, t2) infer env (Let [(x, e1)] e2) = fresh - >>= \tv-> infer ('Data.Map'.put x (Forall [] tv) env) e1 - >>= \(s1, t1)->infer ('Data.Map'.put x (generalize (apply s1 env) t1) env) e2 + >>= \tv-> let env` = 'Data.Map'.put x (Forall [] tv) env + in infer env` e1 + >>= \(s1,t1)-> infer ('Data.Map'.put x (generalize (apply s1 env`) t1) env`) e2 >>= \(s2, t2)->pure (s1 oo s2, t2) diff --git a/tests/preamble.mfp b/tests/preamble.mfp index 617b195..8c01e96 100644 --- a/tests/preamble.mfp +++ b/tests/preamble.mfp @@ -6,4 +6,4 @@ $ ifxr 0 x y = x y; + ifxl 6 = code add; if = code if; fac i = if (i == 0) 1 (i * fac (i - 1)); -start = fac 15; +start = fac;