【问题标题】:Is any normalization of a function to a curried form considered currying?是否将函数归一化为柯里化形式被认为是柯里化?
【发布时间】:2013-06-03 00:38:19
【问题描述】:

我正在阅读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); }

【问题讨论】:

  • 可以肯定的是,这仍然是 currying。这不是一个单一的柯里化操作,而是多个柯里化操作,但柯里化仍然是你正在做的事情。
  • 我认为答案是肯定的,但这个问题可能更适合programmers.stackexchange.com
  • @p.s.w.g - 这似乎在我的范围内 - 我认为如果这不被认为是 currying,那么使用函数式语言的开发人员可能有一个术语来指代这个。一般来说,术语问题已经考虑到主题(例如stackoverflow.com/questions/521893/…
  • @Servy,当柯里化操作发生在“嵌套级别”时,是否需要进一步区分?例如Func&lt;T1,Func&lt;T2,T3,T4&gt;&gt; 只需要一个柯里化操作就可以采用柯里化形式,但它必须发生在我所说的“嵌套级别”
  • 这当然是本着柯里化的精神。我可以毫无问题地调用这些柯里化。

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


【解决方案1】:

来自wikipedia

.. 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

所以,答案是肯定的;这些是柯里化函数。

请注意:不是正确的柯里化函数签名:

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

因为函数的输出不是一个函数链,每个函数都有一个参数。因此只有这样一个更简单的弱类型柯里化签名

Func<T1, T2, TResult>           => Func<T1, Func<T2, TResult>>

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

【讨论】:

    猜你喜欢
    • 2016-01-01
    • 1970-01-01
    • 2021-04-04
    • 2021-02-07
    • 2012-10-06
    相关资源
    最近更新 更多