#ifndef LISTOPS
#define LISTOPS
include "setup.td"
def ListOps {
list<int> lst_1 = [10, 20];
list<int> lst_2 = [30, 40];
list<int> lst_c = !listconcat(lst_1, lst_2);
assert !eq(!repr(lst_c), "[10, 20, 30, 40]"), errorStr;
list<int> lst_r = !listremove(lst_c, lst_2);
assert !eq(!repr(lst_r), "[10, 20]"), errorStr;
int h = !head(lst_c);
assert !eq(h, 10), errorStr;
list<int> t = !tail(lst_c);
assert !eq(!repr(t), "[20, 30, 40]"), errorStr;
list<int> lst_s = !listsplat(1, 3);
assert !eq(!repr(lst_s), "[1, 1, 1]"), errorStr;
list<int> foreach_v = !foreach(px, [1,2,3], !mul(px,2));
assert !eq(!repr(foreach_v), "[2, 4, 6]"), errorStr;
list<int> r1 = !range(4);
assert !eq(!repr(r1), "[0, 1, 2, 3]"), errorStr;
list<int> r2 = !range(1, 4);
assert !eq(!repr(r2), "[1, 2, 3]"), errorStr;
list<int> r3 = !range(0, 4, 2);
assert !eq(!repr(r3), "[0, 2]"), errorStr;
list<int> r4 = !range(4, 1, -2);
assert !eq(!repr(r4), "[4, 2]"), errorStr;
list<int> r5 = !range(0, 4, -1);
assert !eq(!repr(r5), "[]"), errorStr;
list<int> r6 = !range(4, 0, 1);
assert !eq(!repr(r6), "[]"), errorStr;
int sum_v = !foldl(0, [1, 1, 1, 1], total, rec, !add(total, rec));
assert !eq(sum_v, 4), errorStr;
string op_string = !foldl("",
[addOp, mulOp, divOp], str, op,
!strconcat(str, ", ", op.name));
assert !eq(op_string, ", add, mul, div"), errorStr;
list<int> filteredList = !filter(x, [1, 2, 3, 4, 5, 6], !eq(x, 3));
assert !eq(!repr(filteredList), "[3]"), errorStr;
list<Op> filteredRecList = !filter(op, [addOp, mulOp, divOp], !eq(op.name, "add"));
assert !eq(filteredRecList[0], addOp), errorStr;
assert !empty([]<int>), errorStr;
assert !empty(r5), errorStr;
assert !empty(r6), errorStr;
list<int> charIndices = !range(["a","b","c"]);
assert !eq(!repr(charIndices), "[0, 1, 2]"), errorStr;
}
#endif