\begin{itemize}
\item Mutual recursion is allowed and type checked, however inference is
not complete.
- \pause
\begin{CleanCode}
flip(n, l) {
if( n <= 0 ) {return l;}
\end{itemize}
\end{frame}
+\begin{frame}[fragile]
+ \frametitle{But wait, there is more!}
+ \framesubtitle{Trouble that is}
+ \begin{itemize}
+ \item Polymorphism is not working great either.
+ \begin{CleanCode}
+id(x) :: a -> a {
+ return x;
+}
+ \end{CleanCode}
+ \pause
+ \item Is typed fun, but when we introduce:
+ \begin{CleanCode}
+var x = id(5);
+var y = id(True);
+ \end{CleanCode}
+ \pause
+ \begin{CleanCode}
+2:12 SemError: Cannot unify types. Expected: Int. Given: Bool
+ \end{CleanCode}
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]
+ \frametitle{But wait, there is more!}
+ \framesubtitle{Trouble that is}
+
+ \begin
+\end{frame}
+
% - Can functions that are defined later in a file call earlier defined functions?
% - Can local variables be defined in terms of other local variables?
% - How do you deal with assignments?
matchFunctions args ft >>= \tres->
mapM semVarDecl vds >>= \newvds->
mapM (checkStmt tres) stmts >>= \newstmts->
- inferReturnType stmts >>= \returntype->
case mt of
- Nothing = reconstructType args tres
+ Nothing = inferReturnType stmts
+ >>= \returntype->reconstructType args tres
>>= \ftype->restoreGamma gamma
>>| putIdent f ftype >>| pure (
FunDecl p f args (Just ftype) newvds newstmts)
- Just t = restoreGamma gamma >>| updateFunType t returntype
- >>= \tt-> pure (FunDecl p f args (Just tt) newvds newstmts)
-
-updateFunType :: Type Type -> Env Type
-updateFunType t1 t2 = unify t1 t2
-updateFunType (t1 ->> t2) t3 = t1 ->> (updateFunType t2 t3)
+ Just t = restoreGamma gamma
+ >>| pure (FunDecl p f args mt newvds newstmts)
inferReturnType :: [Stmt] -> Env Type
inferReturnType [] = pure VoidType
-inferReturnType [ReturnStmt (Just t):rest] = typeExpr t
- >>= \tx->inferReturnType rest >>= \ty->unify tx ty
-inferReturnType [ReturnStmt _:rest] =
- inferReturnType rest >>= \tx-> unify VoidType tx
+inferReturnType [ReturnStmt (Just t):rest] = typeExpr t
+inferReturnType [ReturnStmt _:rest] = pure VoidType
inferReturnType [_:rest] = inferReturnType rest
reconstructType :: [String] Type -> Env Type
unify (ListType t1) (ListType t2) = unify t1 t2 >>| (pure $ ListType t1)
unify (ta1 ->> ta2) (tb1 ->> tb2) = unify ta1 tb1 >>= \ta-> unify ta2 tb2
>>= \tb-> pure (ta ->> tb)
- unify VoidType t = pure t
- unify t VoidType = pure t
unify VoidType VoidType = pure VoidType
unify t1 t2 = liftT $ Left $ UnifyError zero t1 t2