Curry和Partial方法


Curry

Curry-在数学和计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。 要想通过C#实现,就要用到Curry扩展方法。

public static class CurryMethodExtensions
{
    public static Func<A, Func<B, Func<C, R>>> Curry<A, B, C, R>(this Func<A, B, C, R> f)
    {
        return a => b => c => f(a, b, c);
    }
}

扩展方法的使用一开始是有点势不可挡的。

Func<int, int, int, int> addNumbers = (x, y, z) => x + y + z;
var f1 = addNumbers.Curry();
Func<int, Func<int, int>> f2 = f1(3);
Func<int, int> f3 = f2(4);
Console.WriteLine(f3(5));

不同函数的返回类型可通过var关键字进行交换。 官方文档:https://en.wikipedia.org/wiki/Currying#/Contrast_with_partial_function_application

Partial

Partial - 在计算机科学中,部分应用程序(或部分功能的应用程序)是指固定的一些参数的函数,产生另一种更小参数数量功能的过程。

public static class CurryMethodExtensions
{
    public static Func<C, R> Partial<A, B, C, R>(this Func<A, B, C, R> f, A a, B b)
    {
        return c => f(a, b, c);
    }
}

Partial的扩展方法比Curry的更简单直观。

Func<int, int, int, int> sumNumbers = (x, y, z) => x + y + z;
Func<int, int> f4 = sumNumbers.Partial(3, 4);
Console.WriteLine(f4(5));

同样,不同类型的代理可通过var关键字来声明。 官方文档:https://en.wikipedia.org/wiki/Partial_application

完整示例

/// <summary>
/// Curry和Partial方法
/// </summary>
public static class CurryMethodExtensions
{
    /// <summary>
    /// Curry-在数学和计算机科学中,
    /// 柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,
    /// 并且返回接受余下的参数且返回结果的新函数的技术。
    /// </summary>
    /// <typeparam name="A"></typeparam>
    /// <typeparam name="B"></typeparam>
    /// <typeparam name="C"></typeparam>
    /// <typeparam name="R"></typeparam>
    /// <param name="f"></param>
    /// <returns>不同函数的返回类型可通过var关键字进行交换。</returns>
    public static Func<A, Func<B, Func<C, R>>> Curry<A, B, C, R>(this Func<A, B, C, R> f)
    {
        return a => b => c => f(a, b, c);
    }

    /// <summary>
    /// 在计算机科学中,部分应用程序(或部分功能的应用程序)是指固定的一些参数的函数,
    /// 产生另一种更小参数数量功能的过程。
    /// </summary>
    /// <typeparam name="A"></typeparam>
    /// <typeparam name="B"></typeparam>
    /// <typeparam name="C"></typeparam>
    /// <typeparam name="R"></typeparam>
    /// <param name="f"></param>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns>不同类型的代理可通过var关键字来声明</returns>
    public static Func<C, R> Partial<A, B, C, R>(this Func<A, B, C, R> f, A a, B b)
    {
        return c => f(a, b, c);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Func<int, int, int, int> addNumbers = (x, y, z) => x + y + z;
        var f1 = addNumbers.Curry();
        Func<int, Func<int, int>> f2 = f1(3);
        Func<int, int> f3 = f2(4);
        Console.WriteLine(f3(5));


        Func<int, int, int, int> sumNumbers = (x, y, z) => x + y + z;
        Func<int, int> f4 = sumNumbers.Partial(3, 4);
        Console.WriteLine(f4(5));

        Console.ReadKey(true);
    }
}

知识共享许可协议
《Curry和Partial方法》 常伟华 创作。
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议 | 3.0 中国大陆许可协议进行许可。

站内公告

A PHP Error was encountered

Severity: Core Warning

Message: PHP Startup: zip: Unable to initialize module Module compiled with module API=20060613 PHP compiled with module API=20090626 These options need to match

Filename: Unknown

Line Number: 0

Backtrace: