Your choices
Your choice of predicate is as follows:
Two concatenable terms as input (can split)
- atom_concat/3 (ISO)
- string_concat/3
Two more general concatenable terms as input (cannot split because arguments 1 and 2 are too general)
A list of concatenable terms as input (never split)
- atomic_list_concat/2 - generates atom at argument 2. Refuses string at argument 2 in accept mode (that's likely a bug).
- atomics_to_string/2 - generates string at argument 2. Refuses atom at argument 2 in accept mode (that's likely a bug).
A list of concatenable terms as input, and intersperse another string (can split at interspersed string)
- atomic_list_concat/3 - concatenate with separator ("intersperse", "join"). Refuses string at argument 3 in accept mode (that's likely a bug).
- atomics_to_string/3 - concatenate with separator ("intersperse", "join"). Refuses atom at argument 3 in accept mode (that's likely a bug).
Test code
:- begin_tests(atom_concat). test("atom_concat/3 generates atom at the 3rd argument") :- atom_concat(a,b,X), assertion(X==ab). test("atom_concat/3 in 'accept mode' allows string at 3rd argument") :- atom_concat(a,b,"ab"). test("atom_concat/3 accepts string at argument 1 and 2") :- atom_concat("a",b,X), assertion(X==ab), atom_concat(a,"b",Y), assertion(Y==ab), atom_concat("a","b",Z), assertion(Z==ab). test("atom_concat/3 actually accepts atomic at argument 1 and 2 and even 3") :- atom_concat(1,2,X), assertion(X=='12'), atom_concat(1,2,12). test("atom_concat/3 generates possible inputs") :- bagof(X-Y,atom_concat(X,Y,ab),Bag1), assertion(Bag1 == [''-ab,a-b,ab-'']), bagof(X-Y,atom_concat(X,Y,12),Bag2), assertion(Bag2 == [''-'12','1'-'2','12'-'']). test("atom_concat/3 concatenating rationals is weird") :- atom_concat(1r12,2r4,X), assertion(X == '1r121r2'). :- end_tests(atom_concat).
An alternative implementation
stringy_concat.pl
which calls string_concat/3 and atom_string/2 as needed.
?- stringy_concat([foo,"bar",baz,"quux"],R,string). R = "foobarbazquux".
?- stringy_concat([foo,"bar",baz,"quux"],R,atom). R = foobarbazquux.
?- stringy_concat([foo,"bar",baz,"quux"],R,Type). R = foobarbazquux, Type = atom ; R = "foobarbazquux", Type = string.