anchor.diff:            %% L = ?list(Contents, Termination, ?unknown_qual),
             %% erlang:error({illegal_list, L})
         end,
  -      "maybe_improper_list()";
  +      F:text("maybe_improper_list()");
       _ -> 
         case t_is_subtype(t_nil(), Termination) of
   	true ->
  -	  "maybe_improper_list("++ContentString++","
  -	    ++t_to_string(Termination, RecDict)++")";
  +	  F:concat( F:text("maybe_improper_list("),
  +		    ContentString,
  +		    F:text(","),
  +		    t_to_string(F, Termination, RecDict),
  +		    F:text(")") );
   	false ->
  -	  "improper_list("++ContentString++","
  -	    ++t_to_string(Termination, RecDict)++")"
  +	  F:concat( F:text("improper_list("), ContentString, F:text(","),
  +		    t_to_string(F, Termination, RecDict), F:text(")") )
         end
     end;
  -t_to_string(?int_set(Set), _RecDict) ->
  -  set_to_string(Set);
  -t_to_string(?byte, _RecDict) -> "byte()";
  -t_to_string(?char, _RecDict) -> "char()";
  -t_to_string(?integer_pos, _RecDict) -> "pos_integer()";
  -t_to_string(?integer_non_neg, _RecDict) -> "non_neg_integer()";
  -t_to_string(?integer_neg, _RecDict) -> "neg_integer()";
  -t_to_string(?int_range(From, To), _RecDict) ->
  -  flat_format("~w..~w", [From, To]);
  -t_to_string(?integer(?any), _RecDict) -> "integer()";
  -t_to_string(?float, _RecDict) -> "float()";
  -t_to_string(?number(?any, ?unknown_qual), _RecDict) -> "number()";
  -t_to_string(?product(List), RecDict) -> 
  -  "<" ++ comma_sequence(List, RecDict) ++ ">";
  -t_to_string(?remote(Set), RecDict) ->
  -  string:join([case Args =:= [] of
  -		 true  -> flat_format("~w:~w()", [Mod, Name]);
  -		 false ->
  -		   ArgString = comma_sequence(Args, RecDict),
  -		   flat_format("~w:~w(~s)", [Mod, Name, ArgString])
  -	       end
  -	       || #remote{mod = Mod, name = Name, args = Args} <-
  -		    set_to_list(Set)],
  -	      " | ");
  -t_to_string(?map(Pairs), RecDict) ->
  -    "#{" ++ map_pairs_to_string(Pairs,RecDict) ++ "}";
  -t_to_string(?tuple(?any, ?any, ?any), _RecDict) -> "tuple()";
  -t_to_string(?tuple(Elements, _Arity, ?any), RecDict) ->   
  -  "{" ++ comma_sequence(Elements, RecDict) ++ "}";
  -t_to_string(?tuple(Elements, Arity, Tag), RecDict) ->
  +t_to_string(F, ?int_set(Set), _RecDict) ->
  +  set_to_string(F, Set);
  +t_to_string(F, ?byte, _RecDict) -> F:text("byte()");
  +t_to_string(F, ?char, _RecDict) -> F:text("char()");
  +t_to_string(F, ?integer_pos, _RecDict) -> F:text("pos_integer()");
  +t_to_string(F, ?integer_non_neg, _RecDict) -> F:text("non_neg_integer()");
  +t_to_string(F, ?integer_neg, _RecDict) -> F:text("neg_integer()");
  +t_to_string(F, ?int_range(From, To), _RecDict) ->
  +  F:flat_format("~w..~w", [From, To]);
  +t_to_string(F, ?integer(?any), _RecDict) -> F:text("integer()");
  +t_to_string(F, ?float, _RecDict) -> F:text("float()");
  +t_to_string(F, ?number(?any, ?unknown_qual), _RecDict) -> F:text("number()");
  +t_to_string(F, ?product(List), RecDict) ->
  +  F:concat(F:text("<"), F:comma_sequence(List, RecDict), F:text(">"));
  +t_to_string(F, ?remote(Set), RecDict) ->
  +  F:join([ case Args =:= [] of
  +	     true  -> F:flat_format("~w:~w()", [Mod, Name]);
  +	     false ->
  +	       ArgString = F:comma_sequence(Args, RecDict),
  +	       F:flat_format("~w:~w(~s)", [Mod, Name, ArgString])
  +	   end
  +	   || #remote{mod = Mod, name = Name, args = Args} <-
  +	      set_to_list(Set) ],
  +	 F:text(" | "));
  +t_to_string(F, ?map(Pairs), RecDict) ->
  +  F:concat(F:text("#{"), map_pairs_to_string(F, Pairs, RecDict), F:text("}"));
  +t_to_string(F, ?tuple(?any, ?any, ?any), _RecDict) -> F:text("tuple()");
  +t_to_string(F, ?tuple(Elements, _Arity, ?any), RecDict) ->
  +  F:concat(F:text("{"), F:comma_sequence(Elements, RecDict), F:text("}"));
  +t_to_string(F, ?tuple(Elements, Arity, Tag), RecDict) ->
     [TagAtom] = atom_vals(Tag),
     case lookup_record(TagAtom, Arity-1, RecDict) of
  -    error -> "{" ++ comma_sequence(Elements, RecDict) ++ "}";
  +    error -> F:concat(F:text("{"), F:comma_sequence(Elements, RecDict), F:text("}"));
       {ok, FieldNames} ->
         record_to_string(TagAtom, Elements, FieldNames, RecDict)
     end;
  -t_to_string(?tuple_set(_) = T, RecDict) ->
  -  union_sequence(t_tuple_subtypes(T), RecDict);
  -t_to_string(?union(Types), RecDict) ->
  -  union_sequence([T || T <- Types, T =/= ?none], RecDict);
  -t_to_string(?var(Id), _RecDict) when is_atom(Id) ->
  -  flat_format("~s", [atom_to_list(Id)]);
  -t_to_string(?var(Id), _RecDict) when is_integer(Id) ->
  -  flat_format("var(~w)", [Id]).
  -
  -
  -map_pairs_to_string([],_) -> [];
  -map_pairs_to_string(Pairs,RecDict) ->
  -    StrPairs = [{t_to_string(K,RecDict),t_to_string(V,RecDict)}||{K,V}<-Pairs],
  +t_to_string(F, ?tuple_set(_) = T, RecDict) ->
  +  F:union_sequence(t_tuple_subtypes(T), RecDict);
  +t_to_string(F, ?union(Types), RecDict) ->
  +  F:union_sequence([T || T <- Types, T =/= ?none], RecDict);
  +t_to_string(F, ?var(Id), _RecDict) when is_atom(Id) ->
  +  F:flat_format("~s", [atom_to_list(Id)]);
  +t_to_string(F, ?var(Id), _RecDict) when is_integer(Id) ->
  +  F:flat_format("var(~w)", [Id]).
  +
  +
  +map_pairs_to_string(_F, [],_) -> [];
  +map_pairs_to_string(F, Pairs,RecDict) ->
  +    StrPairs = [{t_to_string(F, K,RecDict),t_to_string(F, V,RecDict)}||{K,V}<-Pairs],
       string:join([K ++ "=>" ++ V||{K,V}<-StrPairs], ", ").
   
   
  
positive.code: 
  -spec t_to_string(erl_type(), type_table()) -> string().
  
  t_to_string(?any, _RecDict) ->
    "any()";
  t_to_string(?none, _RecDict) ->
    "none()";
  t_to_string(?unit, _RecDict) ->
    "no_return()";
  t_to_string(?atom(?any), _RecDict) -> 
    "atom()";
  t_to_string(?atom(Set), _RecDict) ->
    case set_size(Set) of
      2 ->
        case set_is_element(true, Set) andalso set_is_element(false, Set) of
  	true -> "boolean()";
  	false -> set_to_string(Set)
        end;
      _ ->
        set_to_string(Set)
    end;
  t_to_string(?bitstr(0, 0), _RecDict) ->
    "<<>>";
  t_to_string(?bitstr(8, 0), _RecDict) ->
    "binary()";
  t_to_string(?bitstr(1, 0), _RecDict) ->
    "bitstring()";
  t_to_string(?bitstr(0, B), _RecDict) ->
    flat_format("<<_:~w>>", [B]);
  t_to_string(?bitstr(U, 0), _RecDict) ->
    flat_format("<<_:_*~w>>", [U]);
  t_to_string(?bitstr(U, B), _RecDict) ->
    flat_format("<<_:~w,_:_*~w>>", [B, U]);
  t_to_string(?function(?any, ?any), _RecDict) ->
    "fun()";
  t_to_string(?function(?any, Range), RecDict) ->
    "fun((...) -> " ++ t_to_string(Range, RecDict) ++ ")";
  t_to_string(?function(?product(ArgList), Range), RecDict) ->
    "fun((" ++ comma_sequence(ArgList, RecDict) ++ ") -> "
      ++ t_to_string(Range, RecDict) ++ ")";
  t_to_string(?identifier(Set), _RecDict) ->
    case Set of
      ?any -> "identifier()";
      _ ->
        string:join([flat_format("~w()", [T]) || T <- set_to_list(Set)], " | ")
    end;
  t_to_string(?opaque(Set), RecDict) ->
    string:join([opaque_type(Mod, Name, Args, S, RecDict) ||
                  #opaque{mod = Mod, name = Name, struct = S, args = Args}
                    <- set_to_list(Set)],
  	      " | ");
  t_to_string(?matchstate(Pres, Slots), RecDict) ->
    flat_format("ms(~s,~s)", [t_to_string(Pres, RecDict),
                              t_to_string(Slots,RecDict)]);
  t_to_string(?nil, _RecDict) ->
    "[]";
  t_to_string(?nonempty_list(Contents, Termination), RecDict) ->
    ContentString = t_to_string(Contents, RecDict),
    case Termination of
      ?nil ->
        case Contents of
  	?char -> "nonempty_string()";
  	_ -> "["++ContentString++",...]"
        end;
      ?any -> 
        %% Just a safety check.
  
negative.code: t_form_to_string({type, _L, range, [From, To]} = Type) ->
    case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of
      {{integer, _, FromVal}, {integer, _, ToVal}} ->
        erl_types_flat_fmt:flat_format("~w..~w", [FromVal, ToVal]);
      _ -> erl_types_flat_fmt:flat_format("Badly formed type ~w",[Type])
    end;
  t_form_to_string({type, _L, record, [{atom, _, Name}]}) ->
    erl_types_flat_fmt:flat_format("#~w{}", [Name]);
  t_form_to_string({type, _L, record, [{atom, _, Name}|Fields]}) ->
    FieldString = string:join(t_form_to_string_list(Fields), ","),
    erl_types_flat_fmt:flat_format("#~w{~s}", [Name, FieldString]);
  t_form_to_string({type, _L, field_type, [{atom, _, Name}, Type]}) ->
    erl_types_flat_fmt:flat_format("~w::~s", [Name, t_form_to_string(Type)]);
  t_form_to_string({type, _L, term, []}) -> "term()";
  t_form_to_string({type, _L, timeout, []}) -> "timeout()";
  t_form_to_string({type, _L, tuple, any}) -> "tuple()";
  