defaultGamma :: Gamma //includes all default functions
defaultGamma = extend "print" (Forall ["a"] ((IdType "a") ->> VoidType))
$ extend "isEmpty" (Forall ["a"] ((ListType (IdType "a")) ->> BoolType))
- $ extend "read" (Forall [] CharType)
+ $ extend "read" (Forall [] (FuncType CharType))
zero
sem :: AST -> Either [SemError] AST
ftv (TupleType (t1, t2)) = ftv t1 ++ ftv t2
ftv (ListType t) = ftv t
ftv (IdType tvar) = [tvar]
+ ftv (FuncType t) = ftv t
ftv (t1 ->> t2) = ftv t1 ++ ftv t2
ftv _ = []
subst s (TupleType (t1, t2))= TupleType (subst s t1, subst s t2)
subst s (ListType t1) = ListType (subst s t1)
+ subst s (FuncType t) = FuncType (subst s t)
subst s (t1 ->> t2) = (subst s t1) ->> (subst s t2)
subst s t1=:(IdType tvar) = 'Map'.findWithDefault t1 tvar s
subst s t = t
lookup f >>= \expected ->
let accST = (\(s,ts) e->infer e >>= \(s_,et)->pure (compose s_ s,ts++[et])) in
foldM accST (zero,[]) args >>= \(s1, argTs)->
- fresh >>= \tv->
- let given = foldr (->>) tv argTs in
- lift (unify expected given) >>= \s2->
- let fReturnType = subst s2 tv in
- foldM foldFieldSelectors fReturnType fs >>= \returnType ->
- pure (compose s2 s1, returnType)
+ fresh >>= \tv->case expected of
+ FuncType t = pure (s1, t)
+ _ = (let given = foldr (->>) tv argTs in
+ lift (unify expected given) >>= \s2->
+ let fReturnType = subst s2 tv in
+ foldM foldFieldSelectors fReturnType fs >>= \returnType ->
+ pure (compose s2 s1, returnType))
IntExpr _ _ = pure $ (zero, IntType)
BoolExpr _ _ = pure $ (zero, BoolType)