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
|
const std = @import("std");
const typeVerify = @import("util.zig").typeVerify;
/// ```zig
/// (fn (Allocator, fn (fn (a) b, []a, *[]b) void)
/// ```
/// 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.?,
buffer: *[]typeVerify(@TypeOf(func), .{ .@"fn" }).@"fn".return_type.?,
) void {
_=typeVerify(@TypeOf(func), .{ .@"fn" });
// const itemsInfo = typeVerify(@TypeOf(items), .{ .pointer, .array });
// const bufferInfo = typeVerify(@TypeOf(buffer), .{ .pointer });
// const bufferChildInfo = typeVerify(bufferInfo.pointer.child, .{ .pointer, .array });
// switch (itemsInfo) {
// .pointer => |p| if(p.size != .many and p.size != .slice)
// @compileError("Expected pointer of size 'many' or 'slice', found '" ++ @tagName(p.size) ++ "'"),
// else =>{},
// }
// switch (bufferChildInfo) {
// .pointer => |p| if(p.size != .many and p.size != .slice)
// @compileError("Expected pointer of size 'many' or 'slice', found '" ++ @tagName(p.size) ++ "'"),
// else =>{},
// }
for (items, 0..) |item, i|
buffer.*[i] = func(item);
}
/// ```zig
/// (fn (Allocator, fn (fn (a) b, []a) error{OutOfMemory}![]b)
/// ```
/// Map a function onto a list of values, allocating space for the new slice
/// 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,
items: anytype,
) error{OutOfMemory}!blk:{
const funcInfo = typeVerify(@TypeOf(func), .{ .@"fn" });
const itemsInfo = typeVerify(@TypeOf(items), .{ .array, .pointer });
switch (itemsInfo) {
.pointer => |p| if(p.size != .many and p.size != .slice)
@compileError("Expected pointer of size 'many' or 'slice', found " ++ @tagName(p)),
else =>{},
}
break :blk []funcInfo.@"fn".return_type.?;
} {
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);
return result;
}
|