I have some employees:
employee(2,2,'George','Johnson','12/16/1987').
employee(4,3,'Noah','Jones','6/9/1984').
employee(5,4,'Jack','Brown','2/16/1992').
employee(6,6,'Charlie','Davis','3/28/1997').
employee(7,1,'Leo','Miller','6/6/1997').
employee(8,6,'Jacob','Wilson','2/16/1997').
I want to print of all them. I do it so now:
run :- findall(Id, employee(Id, _, _, _, _), L), writeEmployees(L).
writeEmployees([]) :- !.
writeEmployees([Id|T]) :- employee(Id, PosId, FN, LN, Birth),
writeq(employee(Id, PosId, FN, LN, Birth)), nl, writeEmployees(T).
And it works, but it doesn't look ok, I mean, there're too many '_'s and I have to write 'Id, PosId, FN, LN, Birth' string. How can find employee directly in findall()?
Nothing really terribly wrong with what you have. Yes, you have four _
but that's fine if you do not care about any of those 4 arguments.
However, you are skipping those arguments, then just retrieving them again later. If you want to avoid that, you could write your findall
to capture everything you want, then write that list out with maplist
.
run :-
findall(employee(Id, PosId, FN, LN, Birth),
employee(Id, PosId, FN, LN, Birth), Employees),
writeEmployees(Employees).
writeEmployee(E) :- writeq(E), nl.
writeEmployees(Es) :- maplist(writeEmployee, Es).
Ultimately, though, it depends upon the broader application this might fit into. If you are managing employees in a broader case, it really is more efficient to manage them by Id
and then retrieve the details only when you need them, as you currently have. You could, though, rewrite your current writeEmployees
with maplist
:
writeEmployee(Id) :-
employee(Id, PosId, FN, LN, Birth),
writeq(employee(Id, PosId, FN, LN, Birth)), nl.
writeEmployees(EmployeeIds) :-
maplist(writeEmployee, EmployeeIds).