Created
September 21, 2021 21:46
-
-
Save luc65r/3260cc20d9d1c0122552b120944ea2b8 to your computer and use it in GitHub Desktop.
Zig functor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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