aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNic Gaffney <gaffney_nic@protonmail.com>2025-10-28 20:55:06 -0500
committerNic Gaffney <gaffney_nic@protonmail.com>2025-10-28 20:55:06 -0500
commit813b6631de7aa296c23e2471589d66625aa6ce15 (patch)
treebfe69e1d47e97dfe95ff22a6e23b5b46680146f7
parent99c32737fe07bf7dc6094a1326be418ffd00e36f (diff)
downloadfuncz-813b6631de7aa296c23e2471589d66625aa6ce15.tar.gz
scanl added, refactored mapHEADmain
-rw-r--r--src/example.zig15
-rw-r--r--src/filter.zig32
-rw-r--r--src/fold.zig21
-rw-r--r--src/map.zig5
-rw-r--r--src/root.zig7
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");