diff options
Diffstat (limited to 'src/fold.zig')
| -rw-r--r-- | src/fold.zig | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/fold.zig b/src/fold.zig new file mode 100644 index 0000000..6b910d3 --- /dev/null +++ b/src/fold.zig @@ -0,0 +1,54 @@ +const std = @import("std"); +const typeVerify = @import("util.zig").typeVerify; + +/// ```zig +/// (fn (fn (fn (b, a) b, b, []a) void) +/// ``` +/// Folds a list of items over a function with the accumulator as the first arg +/// Type signature: `(b -> a -> b) -> b -> [a] -> b` +/// `func` is of type `b -> a -> b`, where `items` is of type `[a]` and `accumulator` is of type `b`. +/// Haskell equivalent: `foldl func accumulator items` +pub fn foldl( + comptime func: anytype, + accumulator: (typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[0].type.?), + items: ([]typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[1].type.?), +) typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".return_type.? { + var accum_internal = accumulator; + for(items) |i| + accum_internal = func(accum_internal, i); + return accum_internal; +} + +/// ```zig +/// (fn (fn (fn (a, b) b, b, []a) void) +/// ``` +/// Folds a list of items over a function with the accumulator as the second arg +/// Type signature: `(a -> b -> b) -> b -> [a] -> b` +/// `func` is of type `a -> b -> b`, where `items` is of type `[a]` and `accumulator` is of type `b`. +/// Haskell equivalent: `foldr func accumulator items` +pub fn foldr( + comptime func: anytype, + accumulator: (typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[1].type.?), + items: ([]typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[0].type.?), +) typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".return_type.? { + var accum_internal = accumulator; + for(items) |i| + accum_internal = func(i, accum_internal); + return accum_internal; +} + +/// Variant of `foldl` where the first element is the base case +pub fn foldl1( + comptime func: anytype, + items: ([]typeVerify(@TypeOf(func), .{.@"fn"}).@"fn".params[0].type.?) +) typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".return_type.? { + return foldl(func, items[0], items); +} + +/// Variant of `foldr` where the first element is the base case +pub fn foldr1( + comptime func: anytype, + items: ([]typeVerify(@TypeOf(func), .{.@"fn"}).@"fn".params[0].type.?) +) typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".return_type.? { + return foldr(func, items[0], items); +} |
