是否将函数规范化为curry形式?

时间:2013-06-06 20:33:35

标签: c# functional-programming normalization currying higher-order-functions

我正在阅读a blog post about combining higher order functions,它提供了一个“currying”的C#示例。

示例如下:

public static Func<T1, Func<T2, T3>> Curry<T1, T2, T3>
    (Func<T1, T2, T3> function) 
{ return a => b => function(a, b); }

public static Func<T1, Func<T2, Func<T3, T4>>> Curry<T1, T2, T3, T4>
    (Func<T1, T2, T3, T4> function)
{ return a => b => c => function(a, b, c); }

public static Func<T1, Func<T2, Func<T3, Func<T4, T5>>>> Curry<T1, T2, T3, T4, T5>
    (Func<T1, T2, T3, T4, T5> function) 
{ return a => b => c => d => function(a, b, c, d); }

我的问题是,采用其他有效产生相同“咖喱形式”结果的形式的方法是否可以被认为是合理的。

例如,以下方法是否考虑过卷曲?如果没有,那么更合适的命名约定是什么?

public static Func<T1, Func<T2, Func<T3, Func<T4, T5>>>> SomethingLikeCurry<T1, T2, T3, T4, T5>
    (Func<T1, T2, Func<T3, T4, T5>> function) 
{ return a => b => c => d => function(a, b)(c, d); }

public static Func<T1, Func<T2, Func<T3, T4>>> SomethingLikeCurry<T1, T2, T3, T4>
    (Func<T1, T2, Func<T3, T4>> function) 
{ return a => b => c => function(a, b)(c); }

1 个答案:

答案 0 :(得分:0)

来自wikipedia

  

.. currying是一种转换一个函数的技术,该函数接受多个参数(或一个参数元组),使得它可以被称为函数链,每个只有一个参数 ...

你问过关于currying功能的两种方法是什么?让我们简化他们的声明以便于检查:

Func<T1, T2, Func<T3, T4, T5>>  => Func<T1, Func<T2, Func<T3, Func<T4, T5>>>>
^ multiple arguments               ^ all single arguments 
Func<T1, T2, Func<T3, T4>>      => Func<T1, Func<T2, Func<T3, T4>>>
^ multiple arguments               ^ all single arguments

所以,答案是肯定的;这些是currying功能。

请注意:是一个正确的currying函数签名:

Func<T1, T2, Func<T3, T4, T5>>  => Func<T1, Func<T2, Func<T3, T4, T5>>>>

由于函数的输出不是一个函数链,每个函数都有一个参数。因此,只有像这样的更简单的弱类型currying签名

Func<T1, T2, TResult>           => Func<T1, Func<T2, TResult>>
当结果TResult是具有多个参数的函数时,

不会产生currying。引发您兴趣的两种方法只是为了防止这种情况发生在具有一个或两个参数的函数中。当然,在curried版本中,类型T5也可能是一个具有多个参数的函数,因此我们可以在 ad infinitum 上继续。