anchor.diff:  -type type_table() :: dict:dict(record_key() | type_key(),
                                   record_value() | type_value()).
   
  --opaque var_table() :: #{atom() => erl_type()}.
  +-type var_table() :: #{atom() => erl_type()}.
   
   %%-----------------------------------------------------------------------------
   %% Unions
  
positive.code: -spec t_unify(erl_type(), erl_type()) -> t_unify_ret().
  
  t_unify(T1, T2) ->
    {T, VarMap} = t_unify(T1, T2, []),
    {t_subst_kv(T, VarMap), lists:keysort(1, VarMap)}.
  
  t_unify(?var(Id) = T, ?var(Id), VarMap) ->
    {T, VarMap};
  t_unify(?var(Id1) = T, ?var(Id2), VarMap) ->
    case lists:keyfind(Id1, 1, VarMap) of
      false ->
        case lists:keyfind(Id2, 1, VarMap) of
  	false -> {T, [{Id2, T} | VarMap]};
  	{Id2, Type} -> t_unify(T, Type, VarMap)
        end;
      {Id1, Type1} ->
        case lists:keyfind(Id2, 1, VarMap) of
  	false -> {Type1, [{Id2, T} | VarMap]};
  	{Id2, Type2} -> t_unify(Type1, Type2, VarMap)
        end
    end;
  t_unify(?var(Id), Type, VarMap) ->
    case lists:keyfind(Id, 1, VarMap) of
      false -> {Type, [{Id, Type} | VarMap]};
      {Id, VarType} -> t_unify(VarType, Type, VarMap)
    end;
  t_unify(Type, ?var(Id), VarMap) ->
    case lists:keyfind(Id, 1, VarMap) of
      false -> {Type, [{Id, Type} | VarMap]};
      {Id, VarType} -> t_unify(VarType, Type, VarMap)
    end;
  t_unify(?function(Domain1, Range1), ?function(Domain2, Range2), VarMap) ->
    {Domain, VarMap1} = t_unify(Domain1, Domain2, VarMap),
  
negative.code: -export([t_is_identifier/1]).
  -endif.
  
  -export_type([erl_type/0, opaques/0, type_table/0]).
  
  %%-define(DEBUG, true).
  
  