
unifyTypes :: SimpleType -> SimpleType -> (TypeSubst,Bool)


unifyTypes (VarType vtype1) (VarType vtype2) = if (vtype1 == vtype2)
                                                  then (identity,True)
                                                  else (pair2TypeSubst (vtype1, (VarType vtype2)),True)


unifyTypes (VarType vtype) tp = if (occur vtype tp)
                                    then  (identity,False)
                                    else (pair2TypeSubst (vtype,tp),True)

unifyTypes tp (VarType vtype) = unifyTypes (VarType vtype) tp

unifyTypes (ArrowType t1 t2) (ArrowType t3 t4) =  ((if b3 then (compose s2 s1) else identity), b3)
                                                where (s1,b1) = (unifyTypes t1 t3)
                                                      (s2,b2) = (unifyTypes (s1 t2) (s1 t4))
                                                      b3      = (b1 && b2) 
                                                                       


unifiable typ1 typ2 = snd (unifyTypes typ1 typ2)


--Examples:

myType1 = ArrowType (VarType (TypeVar 1)) (VarType (TypeVar 1))

myType2 = ArrowType 
                   (ArrowType 
                            (VarType (TypeVar 2)) 
                            (VarType (TypeVar 2))
                    ) 
                   (ArrowType 
                            (VarType (TypeVar 3)) 
                            (ArrowType 
                                     (VarType (TypeVar 3)) 
                                     (VarType (TypeVar 2))
                             )
                    )

myType3 = ArrowType (ArrowType (VarType (TypeVar 1)) (VarType (TypeVar 2))) (VarType (TypeVar 1))

myType4 = ArrowType (ArrowType (VarType (TypeVar 3)) (VarType (TypeVar 2))) (VarType (TypeVar 1))


pairA = unifyTypes myType1 myType2


pairB = unifyTypes myType2 myType4

myType5 =  (fst pairB) myType2
 




