// Higher-order Iter helpers: Map / Filter / Fold with closures import Std::Io::{PrintLine, PrintInt}; import Std::Array::{ Array, Array_New, Array_Push, Array_Get, Array_Len, Array_Free }; import Std::Iter::{ Array_Iter, Iter, Iter_MapInt, Iter_FilterInt, Iter_FoldInt, Iter_AnyInt, Iter_AllInt, Iter_SumInt, Iter_ForEachInt }; import Std::Test::{Test_AssertEqInt, Test_AssertTrue, Test_AssertFalse, Test_Pass}; func Double(x: int) -> int { return x * 2; } func IsEven(x: int) -> bool { return (x % 2) == 0; } func Add(acc: int, x: int) -> int { return acc + x; } func Main() -> int { var nums: Array = Array_New(8); Array_Push(&nums, 1); Array_Push(&nums, 2); Array_Push(&nums, 3); Array_Push(&nums, 4); Array_Push(&nums, 5); // Map with named function let it1: Iter = Array_Iter(&nums); var doubled: Array = Iter_MapInt(&it1, Double); Test_AssertEqInt(Array_Len(&doubled) as int, 5); Test_AssertEqInt(Array_Get(&doubled, 0), 2); Test_AssertEqInt(Array_Get(&doubled, 4), 10); // Filter with named predicate let it2: Iter = Array_Iter(&nums); var evens: Array = Iter_FilterInt(&it2, IsEven); Test_AssertEqInt(Array_Len(&evens) as int, 2); Test_AssertEqInt(Array_Get(&evens, 0), 2); Test_AssertEqInt(Array_Get(&evens, 1), 4); // Fold with named combiner let it3: Iter = Array_Iter(&nums); let sum: int = Iter_FoldInt(&it3, 0, Add); Test_AssertEqInt(sum, 15); let itSum: Iter = Array_Iter(&nums); Test_AssertEqInt(Iter_SumInt(&itSum), 15); // Map with capturing closure let scale: int = 10; let it4: Iter = Array_Iter(&nums); var scaled: Array = Iter_MapInt(&it4, |x: int| -> int { return x * scale; }); Test_AssertEqInt(Array_Get(&scaled, 0), 10); Test_AssertEqInt(Array_Get(&scaled, 2), 30); // Filter with closure let minVal: int = 3; let it5: Iter = Array_Iter(&nums); var big: Array = Iter_FilterInt(&it5, |x: int| -> bool { return x >= minVal; }); Test_AssertEqInt(Array_Len(&big) as int, 3); Test_AssertEqInt(Array_Get(&big, 0), 3); // Fold with closure let it6: Iter = Array_Iter(&nums); let prod: int = Iter_FoldInt(&it6, 1, |a: int, b: int| -> int { return a * b; }); Test_AssertEqInt(prod, 120); // 1*2*3*4*5 // Any / All let itAny: Iter = Array_Iter(&nums); Test_AssertTrue(Iter_AnyInt(&itAny, IsEven)); let itAll: Iter = Array_Iter(&nums); Test_AssertFalse(Iter_AllInt(&itAll, IsEven)); let itEv: Iter = Array_Iter(&evens); Test_AssertTrue(Iter_AllInt(&itEv, IsEven)); // ForEach (print via side-effect free assert path — just call Double) let it7: Iter = Array_Iter(&nums); Iter_ForEachInt(&it7, Double); PrintInt(sum); PrintLine(""); PrintInt(prod); PrintLine(""); Test_Pass("iter_hof"); Array_Free(&nums); Array_Free(&doubled); Array_Free(&evens); Array_Free(&scaled); Array_Free(&big); return 0; }