module Lambda.Type
( -- * Types
Type(..)
+ -- * Type inference
+ , algW
) where
import Lambda.Term
data HMTerm = HMTerm Term TypeScheme | HMLet VarName HMTerm HMTerm TypeScheme
+type Substitution = TypeScheme -> TypeScheme
+
fresh :: TypeVarName
fresh = undefined
substitute :: TypeScheme -> TypeVarName -> TypeScheme -> TypeScheme
substitute = undefined
-unify :: TypeScheme -> TypeScheme -> Either String TypeScheme
-unify = undefined
+unify :: TypeScheme -> TypeScheme -> Either String Substitution
+unify (TScheme (Primitive a)) (TScheme (Primitive b)) | a == b = Right id
+unify (TScheme (TypeVar a)) (TScheme (TypeVar b)) | a == b = Right id
+unify a b = Left "cannot unify " ++ show a ++ " with " ++ show b
algW :: HMTerm -> Either String TypeScheme
algW (HMTerm (Var _) t) = Right t
algW (HMTerm (Lambda x t) (TScheme p)) = do
let v = TScheme (TypeVar fresh)
np <- substitute v x t
- return $ unify p np
+ unify p np
algW (HMTerm (App u v) t) = do
tu <- algW u
tv <- algW v
unify a tv
return b
_ -> Left $ "cannot apply " ++ show tu ++ " to " ++ show tv
-
-
-