c# - 功能构成

标签 c# functional-programming

Compose 函数下方。如果 fg 是返回值的一元函数,则 Compose(f,g) 返回一个在 x 上调用时的函数 执行等同于 f(g(x))

static Func<X, Z> Compose<Z, Y, X>(Func<Y, Z> f,Func<X, Y> g) 
{ return x => f(g(x)); }

这里有几个简单的 Func 值可以组合:

Func<int, bool> is_zero = x => { return x == 0; };

Func<int, int> mod_by_2 = x => { return x % 2; };

例如这有效:

Console.WriteLine(Compose(is_zero, mod_by_2)(4));

但是,如果我改为使用这些等效的静态方法:

static bool IsZero(int n) { return n == 0; }

static int ModBy2(int n) { return n % 2; }

同样的例子不适用于那些。 IE。这会产生编译时错误:

Console.WriteLine(Compose(IsZero, ModBy2)(4));

将类型显式传递给 Compose 解决了这个问题:

Console.WriteLine(Compose<bool, int, int>(IsZero, ModBy2)(4));

有没有办法编写 Compose 使其适用于没有显式类型的静态方法?

这是实现 Compose 的好方法吗?任何人都可以对此进行改进吗?

最佳答案

这里的问题不是static 方法的使用,而是方法组的使用。当您将函数名称用作表达式而不调用它时,它就是一个方法组,必须经过方法组转换。你会遇到与实例方法完全相同的问题。

您遇到的问题是 C# 无法对方法组进行返回类型推断。使用 Compose(IsZero, ModBy2)) 需要为 IsZeroModBy2 推断返回类型,因此此操作失败。

这是 C# 编译器推理能力的一个已知限制。 Eric Lippert 写了一篇关于这个特定主题的广泛博客文章,其中详细介绍了这个问题

关于c# - 功能构成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8719929/

相关文章:

c# - 在 C# 中,如何确定一个列表是否包含另一个列表中的任何项目?

scala - 如何在 Scala 中对函数进行柯里化(Currying)

list - 按第二个元组元素对元组列表进行排序

c# - 即使没有空检查,使用 "as"而不是强制转换是否有意义?

c# - 如何使用 NET Math.Round(<decimal>,<int>,MidpointRounding.AwayFromZero) 正确舍入

c# - 捕获正则表达式 C# 中的特定或组

functional-programming - Elixir 中是否有等效于 Haskell 的 init 函数?

.net - 有没有明显的方法来确认一个函数是否是尾递归的?

Scala:从元组数组/RDD中获取第n个元素的总和

c# - 如何使用 Process.Start 启动管道和重定向命令?