/** Modular function type */ { config, lib, ... }: let inherit (lib) mkOption types; inherit (types) submodule functionTo optionType ; in { options = { input-type = mkOption { type = optionType; }; output-type = mkOption { type = optionType; }; function-type = mkOption { type = optionType; readOnly = true; default = functionTo config.output-type; }; wrapper-type = mkOption { type = optionType; readOnly = true; default = functionTo (submodule { options = { input = mkOption { type = config.input-type; }; output = mkOption { type = config.output-type; }; }; }); }; implementation = mkOption { type = config.function-type; default = _: { }; }; wrapper = mkOption { type = config.wrapper-type; readOnly = true; default = input: fn: { inherit input; output = config.implementation fn.config.input; }; }; apply = mkOption { type = config.function-type; readOnly = true; default = input: (config.wrapper input).output; }; }; }