The
formatTable from the ODBC demo program example is an extensive use of these predicates:
Code: Select all
constants
separator = "|".
predicates
formatTable : (string** Table) -> string TableAsText.
clauses
formatTable(RowsList) = TableAsText :-
ColumnsLenths = list::map(RowsList, {(Row) = list::map(Row, string::length)}),
if [Head | Tail] = ColumnsLenths then
MaxLengths = list::fold(Tail, {(A, B) = [math::max(Aj, Bj) || tuple(Aj, Bj) = list::zip_nd(A, B)]}, Head),
NewRows = list::map(RowsList,
{(Columns) = [string::format("% % ", separator, Col) ||
tuple(C, Length) = list::zip_nd(Columns, MaxLengths),
SpaceAc = Length - string::length(C),
Col = string::concat(C, string::create(SpaceAc, " "))] }),
NewRowsAsStrings = list::map(NewRows, {(ColList) = string::concat(string::concatList(ColList), separator)}),
TableAsText = string::concatWithDelimiter(NewRowsAsStrings, "\n")
else
TableAsText = ""
end if.
If is quite advanced because it works on a two level list. A Table is a list of rows, each of which is a list of strings (i.e. the values in the columns).
The ColumnsLenghts is a similar shaped "table" containing the length of the strings insted of the strings themselves. It is a two level
map, because the table is a two level list.
The
fold in the
if is the most complex operation in the code. If you understand that you understand everything
.
The purpose of the
fold is to calculate a list containg the (for each column) largest string length in that column. The fold runs over the rows in Tail and uses Head as initial value. If Tail is empty Head contains the longest lenghts. The function in the fold recieves a row A and an accumulated result B, and it must calculates the next accumulated result.
First it zip the two list together, i.e. the current row and the acumulated result, then it creates a list by selecting the largest of each of these two elements.
Got that
?.
The next step is to create a table of formatted values prefixed with the initial table seperator "|". For each row it zip string values together with the max-width os the corresponding column, and then it format each of these pairs into the desired result.
NewRowsAsStrings is the result of concatenating all the values in each row together with terminating separator. Finally TableAsText is the result of contanating the rows separated by new-lines.