Skip to content

Instantly share code, notes, and snippets.

@luc65r
Created September 21, 2021 21:46
Show Gist options
  • Save luc65r/3260cc20d9d1c0122552b120944ea2b8 to your computer and use it in GitHub Desktop.
Save luc65r/3260cc20d9d1c0122552b120944ea2b8 to your computer and use it in GitHub Desktop.
Zig functor
const std = @import("std");
const expect = std.testing.expect;
fn Functor(
comptime F: fn (comptime type) type,
) type {
return struct {
fmap: fmap_type,
const Self = @This();
const fmap_type = @TypeOf(struct {
fn f(comptime A: type, comptime B: type, g: fn (A) B, x: F(A)) F(B) {}
}.f);
pub fn init(comptime fmap: fmap_type) Self {
return .{
.fmap = fmap,
};
}
};
}
fn inc(
comptime F: fn (comptime type) type,
comptime Func: anytype, // TODO: Functor(F)
comptime T: type,
x: F(T),
) F(T) {
return Func.fmap(T, T, struct {
fn f(y: T) T {
return y + 1;
}
}.f, x);
}
fn Maybe(comptime A: type) type {
return union(enum) {
none,
some: A,
};
}
const MaybeFunctor = Functor(Maybe).init(struct {
fn f(comptime A: type, comptime B: type, g: fn (A) B, m: Maybe(A)) Maybe(B) {
return switch (m) {
.none => .none,
.some => |x| Maybe(B){ .some = g(x) },
};
}
}.f);
test "hkt" {
const a = Maybe(usize){ .some = 2 };
const b = inc(Maybe, MaybeFunctor, usize, a);
try expect(b.some == 3);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment