第九章 柯里化

什么是柯里化

DDDD

柯里化实践

  1. 识别函数:

    1. 有多个参数
    2. 似乎常只使用部分参数
    3. 参数上天然可以分阶段传入
  2. 定义函数:

    1. 将转化为一系列嵌套的单参数函数。每个函数返回另一个函数,直到所有参数都被传入

柯里化会导致一些繁琐,但在一些情况下,这会非常实用

如配置

public static Func<NotificationType, Func<int, Action<string>>>
CurryNotificationConfig()
{
return notificationType => maxNotificationsPerMinute => recipientEmail =>
{
Console.WriteLine($"配置 {notificationType} 通知:收件人 {recipientEmail},每分钟最多 {maxNotificationsPerMinute} 条");
};
}
var configureNotifications = CurryNotificationConfig();

// 邮件通知配置
var configureEmailNotifications = configureNotifications(NotificationType.Email);

// 为普通用户设置每分钟 10 条
var configureUserNotifications = configureEmailNotifications(10);
configureUserNotifications("alice@example.com");
configureUserNotifications("bob@example.com");

// 为版主设置每分钟 50 条
var configureModeratorNotifications = configureEmailNotifications(50);
configureModeratorNotifications("moderator1@example.com");

// 为管理员设置每分钟 100 条
var configureAdminNotifications = configureEmailNotifications(100);
configureAdminNotifications("admin1@example.com");

按钮

public static Func<string, Func<EventArgs, void>> CurryButtonClickHandler()
{
return buttonName => eventArgs =>
{
Console.WriteLine($"按钮 {buttonName} 被点击!");
// 其他处理逻辑
};
}
var handleButtonClick = CurryButtonClickHandler();

var handleSaveClick = handleButtonClick("保存");
var handleCancelClick = handleButtonClick("取消");

saveButton.Click += (sender, e) => handleSaveClick(e);
cancelButton.Click += (sender, e) => handleCancelClick(e);

日志

public static Func<string, Func<string, void>> CurryLogMessage()
{
return logLevel => message =>
{
Console.WriteLine($"{logLevel}: {message}");
// 用指定的日志级别输出消息
};
}
var logMessage = CurryLogMessage(); // 获取总入口
var logError = logMessage("ERROR"); // 先固定日志级别为 ERROR
var logWarning = logMessage("WARNING"); // 固定为 WARNING

logError("发生了一个错误。"); // 输出:ERROR: 发生了一个错误。
logWarning("这是一个警告信息。"); // 输出:WARNING: 这是一个警告信息。

优缺点

优点:

缺点:

  • 复杂度up
  • 一定性能开销
  • 调试难度变高