vftrait
A compile-time library for duck type checking.
URL: Verafahn/vftrait
idea from Discussion about |T: Trait|.I think this is a good practice, so I wrote this project.
This project implements a complete satisfyTrait function. After introducing it, you can define a trait (actually a struct) in the project to constrain anytype. I think this can also be considered as an implementation of compile time polymorphism.
satisfyTrait is not simply determining whether a type has the same members as a trait, but rather whether T has a subset that is isomorphic to the trait. This is a more rigorous duck type check than name check.
Example
Let’s implement an iterator trait. It’s simple, just need one association type and one method:
pub const Iterator = struct {
pub const Item = type;
pub fn next(self: *@This()) ?Item {
_ = self;
@compileError("");
}
};
I can implement a number generator. Just like a..b syntax.
pub const Generator = struct {
pub const Item = u32;
start: Item,
end: Item,
pub fn init(start: Item, end: Item) @This() {
return .{ .start = start, .end = end };
}
pub fn next(self: *@This()) ?Item {
if (self.start > self.end) return null;
const result = self.start;
self.start += 1;
return result;
}
};
I don’t need to add anything extra. Now Generator has met Iterator’s requirements. Next, I will write another function with trait constraints:
pub fn foreach(iter: anytype, callback: anytype) R: {
const T = @typeInfo(@TypeOf(iter)).pointer.child;
trait.assertSatisfyTrait(IteratorTrait, T);
std.debug.assert(@TypeOf(callback) == fn (T.Item) void);
break :R void;
} {
while (iter.next()) |item| {
callback(item);
}
}
Write a simple code using them:
pub fn main(init: std.process.Init) !void {
_ = init;
var iter = Generator.init(0, 10);
foreach(&iter, struct {
pub fn lambda(item: u16) void {
std.debug.print("{}\n", .{item});
}
}.lambda);
}
Not just one, I can write any type that satisfies the Iterator, and they can all be called through a foreach!
Supported Zig versions
zig 0.16.0
AI / LLM usage disclosure
I used AI to refactor my code (because it was written too messy).