diff options
| author | Nic Gaffney <gaffney_nic@protonmail.com> | 2025-10-28 20:55:06 -0500 |
|---|---|---|
| committer | Nic Gaffney <gaffney_nic@protonmail.com> | 2025-10-28 20:55:06 -0500 |
| commit | 813b6631de7aa296c23e2471589d66625aa6ce15 (patch) | |
| tree | bfe69e1d47e97dfe95ff22a6e23b5b46680146f7 | |
| parent | 99c32737fe07bf7dc6094a1326be418ffd00e36f (diff) | |
| download | funcz-813b6631de7aa296c23e2471589d66625aa6ce15.tar.gz | |
| -rw-r--r-- | src/example.zig | 15 | ||||
| -rw-r--r-- | src/filter.zig | 32 | ||||
| -rw-r--r-- | src/fold.zig | 21 | ||||
| -rw-r--r-- | src/map.zig | 5 | ||||
| -rw-r--r-- | src/root.zig | 7 |
5 files changed, 67 insertions, 13 deletions
diff --git a/src/example.zig b/src/example.zig index e20eb31..7598008 100644 --- a/src/example.zig +++ b/src/example.zig @@ -36,10 +36,13 @@ pub fn main() !void { const itemsSlice: []i32 = items[0..items.len]; var buffer: [16]i32 = undefined; var buffSlice: []i32 = buffer[0..16]; - func.map(iterThenMul2, itemsSlice, &buffSlice); + func.mapBuff(iterThenMul2, itemsSlice, &buffSlice); const bufferAlloc = try func.mapAlloc(allocator, iterThenMul2, itemsSlice); defer allocator.free(bufferAlloc); - const filtered = func.filter(isEven, itemsSlice); + const filtered = try func.filterAlloc(allocator, isEven, itemsSlice); + defer allocator.free(filtered); + const scanned = try func.scanlAlloc(allocator, add, 0, itemsSlice); + defer allocator.free(scanned); std.debug.print("curry(add)(4)(5) = {any}\n", .{ curriedAddResult }); std.debug.print("compose(mul2, iter)(5) = {d}\n", .{ composed }); @@ -56,12 +59,18 @@ pub fn main() !void { } std.debug.print("}}\n", .{}); + std.debug.print("scanl(add, 0, items) = {{ ", .{}); + for(scanned) |item| { + std.debug.print("{d}, ", .{item}); + } + std.debug.print("}}\n", .{}); + std.debug.print("mapAlloc(allocator, compose(mul2, iter), []i32{{ 0, 1, 2, 3, 4 }}) = {{ ", .{}); for(bufferAlloc) |item| { std.debug.print("{d}, ", .{item}); } std.debug.print("}}\n", .{}); - std.debug.print("foldl(add, 0, bufferAlloc) = {d}\n", .{func.foldl(add, 0, bufferAlloc)}); + std.debug.print("foldl(add, 0, items) = {d}\n", .{func.foldl(add, 0, itemsSlice)}); std.debug.print("I(5) = {any}\n", .{c.I(5)}); std.debug.print("K(5)(7) = {any}\n", .{c.K(5)(7)}); std.debug.print("(S K S K)(5)(7) = {any}\n", .{((c.S(c.K)(c.S)(c.K))(mul2)(func.curry(add)(3)))(7)}); diff --git a/src/filter.zig b/src/filter.zig index b9e2167..2395dda 100644 --- a/src/filter.zig +++ b/src/filter.zig @@ -7,16 +7,38 @@ const typeVerify = @import("util.zig").typeVerify; /// Filters a slice, only keeping items give `true` when passed into `func` /// Type signature: `(a -> bool) -> [a] -> [a]` /// `func` is of type `a -> bool`, where `items` is of type `[a]` -pub fn filter( +pub fn filterAlloc( + allocator: std.mem.Allocator, func: anytype, items: []typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[0].type.?, -) []typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[0].type.? { - var output = items; +) ![]typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[0].type.? { + var tmp = items; var i: u32 = 0; for (items) |it| if (func(it)) { - output[i] = it; + tmp[i] = it; i = i + 1; }; - return output[0..i]; + + const output = try allocator.alloc(typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[0].type.?, i); + for (0..i) |j| + output[j] = tmp[i]; + return output; +} + +pub fn filterBuff( + func: anytype, + items: []typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[0].type.?, + buffer: *[]typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[0].type.?, +) void { + var tmp = items; + var i: u32 = 0; + for (items) |it| + if (func(it)) { + tmp[i] = it; + i = i + 1; + }; + + for (0..i) |j| + buffer[j] = tmp[i]; } diff --git a/src/fold.zig b/src/fold.zig index ddaf0a9..f967cdf 100644 --- a/src/fold.zig +++ b/src/fold.zig @@ -50,3 +50,24 @@ pub fn foldr1( ) typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".return_type.? { return foldr(func, items[0], items); } + +pub fn scanlAlloc( + allocator: std.mem.Allocator, + comptime func: anytype, + base: (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 output = try allocator.alloc(typeVerify(@TypeOf(func), .{.@"fn"}).@"fn".return_type.?, items.len); + scanlBuffer(func, base, items, &output); + return output; +} + +pub fn scanlBuffer( + comptime func: anytype, + base: (typeVerify(@TypeOf(func), .{.@"fn"}).@"fn".params[0].type.?), + items: ([]typeVerify(@TypeOf(func), .{.@"fn"}).@"fn".params[1].type.?), + buffer: (*[]typeVerify(@TypeOf(func), .{.@"fn"}).@"fn".return_type.?), +) void { + for (buffer.*, 0..) |*out, i| + out.* = foldl(func, base, items[0..i+1]); +} diff --git a/src/map.zig b/src/map.zig index e0d713d..f66fae0 100644 --- a/src/map.zig +++ b/src/map.zig @@ -7,7 +7,7 @@ const typeVerify = @import("util.zig").typeVerify; /// Map a function onto a list of values, using a buffer /// Type signature: `(a -> b) -> [a] -> [b]` /// `func` is of type `a -> b`, where `items` is of type `[a]` and `buffer` is a pointer to a value of type `[b]`. -pub fn map( +pub fn mapBuff( comptime func: anytype, items: []typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[0].type.?, buffer: *[]typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".return_type.?, @@ -37,7 +37,6 @@ pub fn mapAlloc( } { const funcInfo = typeVerify(@TypeOf(func), .{ .@"fn" }); var result = try allocator.alloc(funcInfo.@"fn".return_type.?, items.len); - for(items, 0..) |item, i| - result[i] = func(item); + mapBuff(func, items, &result); return result; } diff --git a/src/root.zig b/src/root.zig index 9c24261..8d87b50 100644 --- a/src/root.zig +++ b/src/root.zig @@ -1,4 +1,4 @@ -pub const map = @import("map.zig").map; +pub const mapBuff = @import("map.zig").mapBuff; pub const mapAlloc = @import("map.zig").mapAlloc; pub const curry = @import("curry.zig").curry; pub const compose = @import("compose.zig").compose; @@ -6,5 +6,8 @@ pub const foldl = @import("fold.zig").foldl; pub const foldr = @import("fold.zig").foldr; pub const foldl1 = @import("fold.zig").foldl1; pub const foldr1 = @import("fold.zig").foldr1; -pub const filter = @import("filter.zig").filter; +pub const scanlAlloc = @import("fold.zig").scanlAlloc; +pub const scanlBuffer = @import("fold.zig").scanlBuffer; +pub const filterAlloc = @import("filter.zig").filterAlloc; +pub const filterBuff = @import("filter.zig").filterBuff; pub const combinators = @import("combinators.zig"); |
