1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
const std = @import("std");
const typeVerify = @import("util.zig").typeVerify;
/// ```zig
/// (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`.
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) 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`.
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);
}
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]);
}
|