Reputation: 31
I would like to know how to generate a new atom in a list based on existing atom in another list. Given list:
L=[a,b,c,d]
I would like to produce a new list, for example:
P=[a_,b_,c_,d_]
In other words something similar to string addition, e.g.
String str1 = str2 + "_";
Upvotes: 3
Views: 172
Reputation: 10102
The ISO built-in atom_concat/3
is the one to use here:
?- atom_concat(a,'_',A). A = a_.
But how to map now the entire list element-wise? maplist/3
serves this purpose,
?- maplist(atom_concat('_'), [a,b,c,d], Xs). % Wrong! Xs = ['_a','_b','_c','_d'].
... or almost. We added the underscore in front! maplist/3
like many other higher-order predicates adds the additional arguments at the end. In functional programming languages this is called partial application. But in our case, it would be nice to add one argument in front and one at the end. You could make your own definition, like
suffix_prefix_concat(S,P,C) :- atom_concat(P,S,C).
while this works nicely,
?- maplist(suffix_prefix_concat('_'),[a,b,c,d], Xs). Xs = [a_,b_,c_,d_].
... it has its own disadvantages: Inventing a new definition is often very cumbersome: Think of it, you have to figure out a new name for a single use!
A general solution to this is library(lambda)
which is preinstalled in YAP, you can download it for SWI too. See the link for a generic ISO definition which works in any ISO conforming system like GNU, B, SICStus.
?- maplist(\P^C^atom_concat(P,'_',C),[a,b,c,d],Xs). Xs = [a_,b_,c_,d_].
And since the last argument can be avoided, similarly to suffix_prefix_concat
above, we can write more compactly:
?- maplist(\P^atom_concat(P,'_'),[a,b,c,d],Xs). Xs = [a_,b_,c_,d_].
Upvotes: 5
Reputation: 2436
Don't know if it's available in all Prolog systems, but concat_atom/2
would do the trick:
?- concat_atom([a,'_'], A).
A = a_.
Upvotes: 1