Polymorphism support #848

Merged
ghallak merged 53 commits from ghallak/307 into master 2022-06-17 18:09:07 +09:00
Showing only changes of commit ae9b8f8b16 - Show all commits

View File

@ -2747,16 +2747,9 @@ unify1(_Env, X, X, _Variance, _When) ->
unify1(_Env, {id, _, Name}, {id, _, Name}, _Variance, _When) -> unify1(_Env, {id, _, Name}, {id, _, Name}, _Variance, _When) ->
true; true;
unify1(Env, A = {con, _, NameA}, B = {con, _, NameB}, Variance, When) -> unify1(Env, A = {con, _, NameA}, B = {con, _, NameB}, Variance, When) ->
IsSubtype = case Variance of case is_subtype(Env, NameA, NameB, Variance) of
invariant -> NameA == NameB; true -> true;
covariant -> is_subtype(Env, NameA, NameB); false ->
contravariant -> is_subtype(Env, NameB, NameA);
bivariant -> is_subtype(Env, NameA, NameB)
end,
if
IsSubtype ->
true;
true ->
cannot_unify(A, B, When), cannot_unify(A, B, When),
false false
end; end;
@ -2803,6 +2796,15 @@ unify1(_Env, A, B, _Variance, When) ->
cannot_unify(A, B, When), cannot_unify(A, B, When),
false. false.
is_subtype(Env, NameA, NameB, invariant) ->
NameA == NameB;
is_subtype(Env, NameA, NameB, covariant) ->
is_subtype(Env, NameA, NameB);
is_subtype(Env, NameA, NameB, contravariant) ->
is_subtype(Env, NameB, NameA);
is_subtype(Env, NameA, NameB, bivariant) ->
is_subtype(Env, NameA, NameB) orelse is_subtype(Env, NameB, NameA).
is_subtype(Env, Child, Base) -> is_subtype(Env, Child, Base) ->
Parents = maps:get(Child, Env#env.contract_parents, []), Parents = maps:get(Child, Env#env.contract_parents, []),
if if