Below is a program that writes data given in table (or matrix) format in csv file format.
The reason why I use append/3 here is to avoid fail driving, but it feels a little unnatural.
How can I improve the code to make it easier to understand?
put_csv_lines(_csv file,_separator, LL):-
tell(_csv file),
Display one line at a time (LL),
Told.
Display line by line (LL):-
append(_, [L|R], LL),
concat_atom (L, _ delimiter, _ line display),
writef('%t\n', [_line display],
R = [ ].
The main reason why append/3 is used here is when all lines are finished with the last sub-target R=[] Because I want to end the predicate with the truth.If there is no problem, member/2 should be fine.
Display one line at a time (Outstream, LL):-
member(L,LL),
concat_atom (L, _ delimiter, _ line display),
writef(_line feed, '%t\n', [_line display],
write (Outstream,_line display with new line),
fail.
display one line at a time
The one who disliked this style is the definition using append/3 above.Now, what else? Is there an alternative expression?
prolog
I will comment as a questioner.
Why don't we use forall/2?I was looking forward to hearing that
You answered as expected.
I wrote it as a comment to the respondents above, but it's hard to read, so I'll rewrite it.
Code called failed drive
foo(L):-
member(A,L),
writef('%t\n', [A]),
fail.
foo(_).
Use this for all/2 and
foo(L):-
forall(member(A,L),writef('%t\n',[A]))
It's a refreshing rewrite.
For all (P, Q) is true in all cases where P becomes true, so is Q.That's what it means.
If P is true and Q is false, forall/2 itself fails.
Forall/2 has the above relationship between P and Q.Alternatively, it is a predicate for examining relationships
It can also be said that
However, in the above example, the predicate defining the relationship is used to express procedural conjunctions.
Yes.
I like to use this expression because I think it's OK, but I have something to keep in mind.That's
In the Q-side section, there should be no cases where the code above does not reach the fail.
This is only writef/2 here, so it is obvious that this will be true and fail, but
If the code in Q is large, complicated, or contains Exception,
I suspect that there may be cases where the failure has not been reached, so I need to crush it.
Yes.
You can combine forall/2 and member/2 for repeat processing.
save_as_csv_file (File, Separator, Table):-
open(File, write, Out),
for all (member(Row, Table),
write_csv_line (Out, Separator, Row),
close(Out),
!.
write_csv_line(Out, Separator, Row):-
concat_atom(Row, Separator, Line),
writef (LineNL, '%t\n', [Line],
write (Out, LineNL)
This way of writing can honestly express the processing of write_csv_line for each member of the table Row.
Of course, people who read this cannot understand unless they know how to use forall/2.However, a failure-driven loop is not easy to read from the program how far it will backtrack after a failure, putting a strain on the program reader.
350 Environment dependent characters? are displayed.
358 Understanding How to Configure Google API Key
362 rails db:create error: Could not find mysql2-0.5.4 in any of the sources
368 I want to change the format (date and time display) of the legend in chronological order.
356 Where is the memory area of the reference static variable in c#?
© 2023 OneMinuteCode. All rights reserved.