// Joins a list into a string with an optional provided separator. // The string will be in the result field of the generated tuple // from the module. let str_join = module{ // The default separator is a single space. You can override // this when you call the module if desired. sep=" ", // The list is a required parameter. list=NULL, } => { // The function used by reduce to join the list into a string. let joiner = func (acc, item) => select (acc.out == ""), NULL, { true = acc{ out="@@" % (acc.out,item), }, false = acc{ out="@@@" % (acc.out, acc.sep, item), }, }; // The resulting joined string. Reference the result field from the // tuple the module produces to get the joined string. let result = reduce(joiner, {sep=mod.sep, out=""}, (mod.list)).out; }; // Computes the length of the provided list. let len = func(list) => reduce(func(acc, item) => acc + 1, 0, list); // Reverses the provided list. let reverse = func(list) => reduce(func (acc, item) => [item] + acc, [], list); // Enumerates the provided list with optional start and step parameters for the // enumeration. Prodices a list of pairs with the numeration and the list item. // // enumerate{list=["a","b","c"]}.result == [[0, "a"], [1, "b"], [2, "c"]] let enumerate = module{ // Where to start the enumeration. start = 0, // The step amount for each enumeration. step = 1, // The list to enumerate. list = NULL, } => { let reducer = func (acc, item) => acc{ count = acc.count + acc.step, list=acc.list + [[acc.count, item]], }; let result = reduce( reducer, {count=mod.start, list=[], step=mod.step}, (mod.list)).list; }; // zips two lists together. // // zip{list1=[0,2,4],list2=[1,3,5]}.result == [[0, 1], [2, 3], [4, 5]] let zip = module{ list1 = NULL, list2 = NULL, } => { let len = import "std/lists.ucg".len; // Compute the length of each list. let len1 = len(mod.list1); let len2 = len(mod.list2); // Compute the min range of the two lists. let rng = select (len1 >= len2), NULL, { true = 0:(len1 - 1), false = 0:(len2 - 1), }; // The reducer function for the zip operation. let reducer = func (acc, item) => acc{ result = acc.result + [[acc.list1.(item), acc.list2.(item)]], idxs = acc.idxs + [item] }; let acc = { list1 = mod.list1, list2 = mod.list2, result = [], idxs = [], }; // The resulting zipped list. let result = reduce(reducer, acc, rng).result; };