+semVarDecl vd=:(VarDecl pos type ident ex) = unify type ex
+ >>= \et->case et of
+ Left err = pure $ Left err
+ Right t = putIdent ident t >>| pure (Right $ VarDecl pos t ident ex)
+
+typeExpr :: Expr -> Env Type
+typeExpr (IntExpr _ _) = pure $ Right IntType
+typeExpr (CharExpr _ _) = pure $ Right CharType
+typeExpr (BoolExpr _ _) = pure $ Right BoolType
+typeExpr (Op1Expr p UnNegation expr) = unify BoolType expr
+typeExpr (Op1Expr p UnMinus expr) = unify IntType expr
+typeExpr (TupleExpr p (e1, e2)) = typeExpr e1
+ >>= \ete1->typeExpr e2 >>= \ete2->pure (
+ ete1 >>= \te1->ete2 >>= \te2->Right $ TupleType (te1, te2))
+//Int
+typeExpr (Op2Expr p e1 BiPlus e2) = unify IntType e1 >>| unify IntType e2
+typeExpr (Op2Expr p e1 BiMinus e2) = unify IntType e1 >>| unify IntType e2
+typeExpr (Op2Expr p e1 BiTimes e2) = unify IntType e1 >>| unify IntType e2
+typeExpr (Op2Expr p e1 BiDivide e2) = unify IntType e1 >>| unify IntType e2
+typeExpr (Op2Expr p e1 BiMod e2) = unify IntType e1 >>| unify IntType e2
+//bool, char of int
+typeExpr (Op2Expr p e1 BiEquals e2) = undef
+typeExpr (Op2Expr p e1 BiUnEqual e2) = undef
+//char of int
+typeExpr (Op2Expr p e1 BiLesser e2) = undef
+typeExpr (Op2Expr p e1 BiGreater e2) = undef
+typeExpr (Op2Expr p e1 BiLesserEq e2) = undef
+typeExpr (Op2Expr p e1 BiGreaterEq e2) = undef
+//bool
+typeExpr (Op2Expr p e1 BiAnd e2) = undef
+typeExpr (Op2Expr p e1 BiOr e2) = undef
+//a
+typeExpr (Op2Expr p e1 BiCons e2) = undef
+//typeExpr (FunExpr Pos FunCall) = undef
+//typeExpr (EmptyListExpr Pos) = undef
+//typeExpr (VarExpr Pos VarDef) = undef //when checking var-expr, be sure to
+//put the infered type
+ //in the context
+
+class unify a :: Type a -> Env Type
+
+instance unify Expr where
+ unify (_ ->> _) e = pure $ Left $ ParseError (extrPos e)
+ "Expression cannot be a higher order function. Yet..."
+ unify VoidType e = pure $ Left $ ParseError (extrPos e)
+ "Expression cannot be a Void type."
+ unify (IdType _) e = pure $ Left $ ParseError (extrPos e)
+ "Expression cannot be an polymorf type."
+ unify VarType e = typeExpr e
+ unify t e = typeExpr e
+ >>= \eithertype->case eithertype of
+ Left e = pure $ Left e
+ Right tex = unify t tex >>= \eitherun->case eitherun of
+ Left err = pure $ Left $ decErr e err
+ Right t = pure $ Right t
+
+instance unify Type where
+ unify IntType IntType = pure $ Right IntType
+ unify BoolType BoolType = pure $ Right BoolType
+ unify CharType CharType = pure $ Right CharType
+ unify t1 t2 = pure $ Left $ UnifyError zero t1 t2
+
+instance zero Pos where
+ zero = {line=0,col=0}