Home > front end >  Is it possible to deduce the function return type from the parameter function?
Is it possible to deduce the function return type from the parameter function?

Time:02-03

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

  • Related