diff options
| author | Nic Gaffney <gaffney_nic@protonmail.com> | 2025-10-28 20:02:47 -0500 |
|---|---|---|
| committer | Nic Gaffney <gaffney_nic@protonmail.com> | 2025-10-28 20:02:47 -0500 |
| commit | 99c32737fe07bf7dc6094a1326be418ffd00e36f (patch) | |
| tree | bc8549038f85586ef4b9724f51ab850193f36d68 | |
| parent | 96e8c19ebdc7c168a1bd243ce1793b2df1480939 (diff) | |
| download | funcz-99c32737fe07bf7dc6094a1326be418ffd00e36f.tar.gz | |
filter implemented
| -rw-r--r-- | src/compose.zig | 1 | ||||
| -rw-r--r-- | src/curry.zig | 1 | ||||
| -rw-r--r-- | src/example.zig | 13 | ||||
| -rw-r--r-- | src/filter.zig | 22 | ||||
| -rw-r--r-- | src/fold.zig | 6 | ||||
| -rw-r--r-- | src/map.zig | 2 | ||||
| -rw-r--r-- | src/root.zig | 1 |
7 files changed, 37 insertions, 9 deletions
diff --git a/src/compose.zig b/src/compose.zig index 61ebb20..442b21b 100644 --- a/src/compose.zig +++ b/src/compose.zig @@ -7,7 +7,6 @@ const typeVerify = @import("util.zig").typeVerify; /// Function composition /// Type signature: (a -> b) -> (b -> c) -> (a -> c) /// `outerFunc` and `innerFunc` are functions of types `b -> c` and `a -> b` respectively -/// Haskell equivalent: `outerFunc . innerFunc` pub fn compose( comptime outerFunc: anytype, comptime innerFunc: anytype diff --git a/src/curry.zig b/src/curry.zig index d196155..73976c2 100644 --- a/src/curry.zig +++ b/src/curry.zig @@ -7,7 +7,6 @@ const std = @import("std"); /// Type signature: (a -> b -> ... -> n -> r) -> a -> b -> ... -> n -> r /// Transforms a function taking multiple arguments into a sequence of functions each taking a single argument /// `func` is a function of type `(a, b, ..., n) -> r` -/// Haskell equivalent: automatic currying (all functions are curried by default) pub fn curry(func: anytype) curryTypeGetter(@TypeOf(func), @TypeOf(func), .{}) { return curryHelper(func, .{}); } diff --git a/src/example.zig b/src/example.zig index 6622726..e20eb31 100644 --- a/src/example.zig +++ b/src/example.zig @@ -18,6 +18,10 @@ fn addThenMultiply(n: i32, m: i32, q: i32) i32 { return (n + m) * q; } +fn isEven(n: i32) bool { + return (@mod(n, 2) == 0); +} + pub fn main() !void { var gpa = std.heap.DebugAllocator(.{}){}; defer _=gpa.deinit(); @@ -28,13 +32,14 @@ pub fn main() !void { const iterThenMul2 = func.compose(mul2, iter); const composed = iterThenMul2(5); // Map - var items = [_]i32{ 0, 1, 2, 3, 4 }; + var items = [_]i32{ 0, 1, 2, 3, 4, 5 }; const itemsSlice: []i32 = items[0..items.len]; var buffer: [16]i32 = undefined; var buffSlice: []i32 = buffer[0..16]; func.map(iterThenMul2, itemsSlice, &buffSlice); const bufferAlloc = try func.mapAlloc(allocator, iterThenMul2, itemsSlice); defer allocator.free(bufferAlloc); + const filtered = func.filter(isEven, itemsSlice); std.debug.print("curry(add)(4)(5) = {any}\n", .{ curriedAddResult }); std.debug.print("compose(mul2, iter)(5) = {d}\n", .{ composed }); @@ -45,6 +50,12 @@ pub fn main() !void { } std.debug.print("}}\n", .{}); + std.debug.print("filter(isEven, bufferAlloc) = {{ ", .{}); + for(filtered) |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}); diff --git a/src/filter.zig b/src/filter.zig new file mode 100644 index 0000000..b9e2167 --- /dev/null +++ b/src/filter.zig @@ -0,0 +1,22 @@ +const std = @import("std"); +const typeVerify = @import("util.zig").typeVerify; + +/// ```zig +/// (fn (fn (fn (a) bool, []a) []a) +/// ``` +/// 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( + func: anytype, + items: []typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[0].type.?, +) []typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[0].type.? { + var output = items; + var i: u32 = 0; + for (items) |it| + if (func(it)) { + output[i] = it; + i = i + 1; + }; + return output[0..i]; +} diff --git a/src/fold.zig b/src/fold.zig index 6b910d3..ddaf0a9 100644 --- a/src/fold.zig +++ b/src/fold.zig @@ -2,12 +2,11 @@ const std = @import("std"); const typeVerify = @import("util.zig").typeVerify; /// ```zig -/// (fn (fn (fn (b, a) b, b, []a) void) +/// (fn (fn (fn (b, a) b, b, []a) b) /// ``` /// 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.?), @@ -20,12 +19,11 @@ pub fn foldl( } /// ```zig -/// (fn (fn (fn (a, b) b, b, []a) void) +/// (fn (fn (fn (a, b) b, b, []a) b) /// ``` /// 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.?), diff --git a/src/map.zig b/src/map.zig index b04366d..e0d713d 100644 --- a/src/map.zig +++ b/src/map.zig @@ -7,7 +7,6 @@ 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]`. -/// Haskell equivalent: `map func items` pub fn map( comptime func: anytype, items: []typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".params[0].type.?, @@ -28,7 +27,6 @@ pub fn map( /// Type signature: `(a -> b) -> [a] -> [b]` /// `func` is of type `a -> b`, where `items` is of type `[a]`. /// `map` will return a slice of type `[b]` -/// Haskell equivalent: `map func items` pub fn mapAlloc( allocator: std.mem.Allocator, func: anytype, diff --git a/src/root.zig b/src/root.zig index 20c6a20..9c24261 100644 --- a/src/root.zig +++ b/src/root.zig @@ -6,4 +6,5 @@ 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 combinators = @import("combinators.zig"); |
