From c034b4a1291a803028eef8b0950a7090ea54b047 Mon Sep 17 00:00:00 2001 From: Nic Gaffney Date: Tue, 21 Oct 2025 00:09:07 -0500 Subject: Currying, Combinators, and organization --- src/compose.zig | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/compose.zig (limited to 'src/compose.zig') diff --git a/src/compose.zig b/src/compose.zig new file mode 100644 index 0000000..61ebb20 --- /dev/null +++ b/src/compose.zig @@ -0,0 +1,28 @@ +const std = @import("std"); +const typeVerify = @import("util.zig").typeVerify; + +/// ```zig +/// (fn (fn (b) c, fn (a) b) fn (a) c) +/// ``` +/// Function composition +/// Type signature: (a -> b) -> (b -> c) -> (a -> c) +/// `outerFunc` and `innerFunc` are functions of types `b -> c` and `a -> b` respectively +/// Haskell equivalent: `outerFunc . innerFunc` +pub fn compose( + comptime outerFunc: anytype, + comptime innerFunc: anytype +) blk:{ + _=typeVerify(@TypeOf(outerFunc), .{ .@"fn" }); + _=typeVerify(@TypeOf(innerFunc), .{ .@"fn" }); + const out = @typeInfo(@TypeOf(outerFunc)).@"fn".return_type.?; + const in = @typeInfo(@TypeOf(innerFunc)).@"fn".params[0].type.?; + break :blk fn(in) out; +} { + const out = @typeInfo(@TypeOf(outerFunc)).@"fn".return_type.?; + const in = @typeInfo(@TypeOf(innerFunc)).@"fn".params[0].type.?; + return struct { + fn func(input: in) out { + return outerFunc(innerFunc(input)); + } + }.func; +} -- cgit v1.2.3