For educational reasons i'm trying to create the simple Option
type in zig. This is my attempt, and it seems to work correctly:
fn Opt(comptime T: type) type {
return union(enum) {
some: T,
none: void,
pub fn of(x: T) Opt(T) {
return .{ .some = x };
}
pub fn map(self: @This(), comptime R: type, comptime mapFn: fn (x: T) R) Opt(R) {
return switch (self) {
.none => .none,
.some => Opt(R).of(mapFn(self.some)),
};
}
};
}
So, the map
takes the function and returns the Opt(R)
, which in turn has the mapFn
return type. What bothers me, is that you have to explicitly pass the R
type to map
:
const opt: Opt(i32) = Opt(i32).of(101);
const newOpt = opt.map(f32, struct {
fn f(x: i32) f32 {
return 1.0 @intToFloat(f32, x);
}
}.f);
My question is: can i avoid passing type (f32
) in opt.map(f32,...
call?
Looks like it should be possible to deduce it from the mapFn
return type.
Is it even possible in zig?
CodePudding user response:
It is possible as long as the function is not generic (eg has 'anytype' as an arg).
pub fn map(self: @This(), comptime mapFn: anytype) Opt(@typeInfo(@TypeOf(mapFn)).Fn.return_type.?) {
const R = @typeInfo(@TypeOf(mapFn)).Fn.return_type.?;
…
Unfortunately, doing this makes errors and editor support worse and it can be harder to understand the type of the function