C# 的函数编程(Functional programming in C#)

编程语言 William 302浏览 0评论

Table of contents

  1. Introduction
  2. Functions as first-class values
    1. Function types
    2. Function values
    3. Function/delegate arithmetic 
  3. C# Functional programming 
    1. Using LINQ
    2. Higher-order functions 
    3. Asynchronous functions
    4. Tuples
    5. Closures 
    6. Recursion 
    7. Partial functions
    8. Curry functions
  4. Conclusion
  5. History 

目录

  1. 介绍
  2. 函数作为值
    1. 函数类型
    2. 函数值
    3. 函数、委托算术
  3. C# 函数编程
    1. 使用 LINQ
    2. 高阶函数
    3. 匿名函数
    4. 元祖Tuples
    5. 闭包
    6. 递归
    7. Partial 函数
    8. Curry 函数
  4. 结论
  5. 历史

Introduction 

Functional programming is a programming paradigm in C# that is frequently combined with object oriented programming. C# enables you to use imperative programming using object-oriented concepts, but you can also use declarative programming. In declarative programming, you are using a more descriptive way to define what you want to do and not how you want to do some action. As an example, imagine that you want to find the top 10 books with price less than 20 ordered by title. In functional programming, you will define something like:

books.Where(price<20).OrderBy(title).Take(10);

Here you just specify that you want to select books where the price is less than 20, order them by title, and take the first ten. As you can see, you do not specify how this should be done – only what you want to do.

介绍

函数式编程是一种编程范式,经常与C#面向对象编程相结合。 C#允许你使用命令式编程,面向对象的概念,但你也可以使用声明式编程。声明式编程使用的是一个更具描述性的方式来定义你想要做什么,而不是你想怎么做一些动作。例如,假设你想找到排名前10位的图书价格低于20有序的标题。在函数式编程中,您将定义是这样的:

books.Where(price<20).OrderBy(title).Take(10);

在此,你指定了price低于20的书,结果按title进行排序,并且只获取前10条记录。

Now you will say "OK, but this is just simple C# LINQ – why are we calling it functional programming"? LINQ is just one implementation library that enables you to use functional programming concepts. However, functional programming is much more, in this article you might find some interesting samples of usage.

Note that there are other languages that have better support for functional programming. An example might be the F# language that has better support for functional programming concepts and you can use it with C# code. However, if you do not want to learn a new language, here you can find what C# provides you in the functional programming area.

函数类型

函数对象必须是某种委托类型. 在C#中,我们可以定义强类型的委托类型或泛型的委托类型,委托可以代表跟这个委托类型有相同参数的方法(静态方法,类方法)的引用. 定义一个委托类型的例子如下:

delegate double MyFunction(double x); 
This delegate defines a prototype of a function that has adoubleargument and returns the result as adoublevalue. Note that only types are important, actual names of methods and their arguments are arbitrary. This delegate type matches a lot of trigonometric functions, logarithm, exponential, polynomial, and other functions. As an example, you can define a function variable that references some math function, executes it via a function variable, and puts the result in some other variable. An example is shown in the following listing:

MyFunction f = Math.Sin;
double y = f(4); //y=sin(4)
f = Math.Exp;
y = f(4); //y=exp(4)

delegate double MyFunction (
double x); 看下这句(见上一段),声明了一个
delegate (委托)类型,参数x是double类型,返回的结果也是double类型。看好了哦,这句的重点是
delegate这个类型,像MyFunction(方法名)以及参数x啥的随便起名(也不是随便还是要meaningful一点的哦)。这个delegate类型搭载了很多三角函数,对数,指数,多项式,等等我们数学上常用到的那些公式。举个例子吧,下面的那4行代码,定义一个
delegate类型的函数变量(f),然后f可以调用好些个数学函数(Math.Sin,Math.Exp),然后通过变量(y)来执行这些数学函数,再把结果放在别的变量中显示。

MyFunction f = Math.Sin;
double y = f(4); //y=sin(4)
f = Math.Exp;
y = f(4); //y=exp(4)
Instead of strongly typed delegates you can use generic function typesFunc<T
1, T
2, T
3, …,T
n, T
result>where T
1, T
2, T
3, …,T
n are types of the arguments (used if the function has some arguments) and T
result is the return type. An example equivalent to the previous code is shown in the following listing:

Func<double, double> f = Math.Sin;
double y = f(4); //y=sin(4)
f = Math.Exp;
y = f(4); //y=exp(4)

要代替强类型委托,你可以使用泛型函数类型Func<T 1, T 2, T 3, …,T n, Tresult> T 1, T 2, T 3, …,T n都是参数类型(用于有很多参数的函数),并且result是返回类型。在下列列表中显示了相当于前面代码的一个示例:

Func<double, double> f = Math.Sin;
double y = f(4); //y=sin(4)
f = Math.Exp;
y = f(4); //y=exp(4)
You can either define your named delegates or use generic types. BesidesFunc, you have two similar generic types:

  • Predicate<T1, T2, T3, …,Tn>that represents a function that returns a true/false value – equivalent toFunc<T1, T2, T3, …,Tn, bool> 
  • Action<T1, T2, T3, …,Tn>that represents a procedure that does not returns any value – equivalent toFunc<T1, T2, T3, …,Tn, void>

你可以定义你的委托名称或者使用泛型类型。基于Func,你有两个类似的泛型类型:

    ● Predicate<T1, T2, T3, …,Tn>表示一个返回true/false的函数 – 相当于Func<T1, T2, T3, …,Tn, bool>

    ● Action<T1, T2, T3, …,Tn> 表示一个没有任何返回值的程序 – 相当于Func<T1, T2, T3, …,Tn, void>

Predicate is a function that takes some arguments and returns either a true or false value. In the following example is shown a predicate function that accepts a string parameter. The value of this function is set toString.IsNullOrEmpty. This function accepts a string argument and returns information whether or not this string is null or empty – therefore it matches thePredicate<string>type.

Predicate<string> isEmptyString = String.IsNullOrEmpty;
if (isEmptyString("Test"))
{
    throw new Exception("'Test' cannot be empty");
}

Instead ofPredicate<string>, you could useFunc<string, bool>.

Predicate 是一个带有很多参数并且返回true 或false的函数。下面的例子显示了一个接收string 参数Predicate函数。这个函数的值设为String.IsNullOrEmpty。这个函数接收一个string 参数并且返回这个string 参数是否为空的信息 – 因此它匹配Predicate<string>类型。

Predicate<string> isEmptyString = String.IsNullOrEmpty;
if (isEmptyString("Test"))
{
    throw new Exception("'Test' cannot be empty");
}

要代替
Predicate<string>,你可以使用Func<string, bool>。

Actions are a kind of procedures  that can be executed. They accept some arguments but return nothing. In the following example is shown one action that accepts string argument and it points to the standardConsole.WriteLinemethod.

Action<string> println = Console.WriteLine;
println("Test");

When an action reference is called with the parameter, the call is forwarded to theConsole.WriteLinemethod. When you use Action types, you just need to define the list of input parameters because there is no result. In this example,Action<string>is equivalent toFunc<string, void>.

Actions 是一种可执行的程序。它接收一些参数但没有返回值。下面这个示例显示了一个接收string参数但指向标准Console.WriteLine 方法的action。

Action<string> println = Console.WriteLine;
println("Test");

当一个
action 引用和参数被调用时,调用被转到了Console.WriteLine 方法。当你使用Action类型,你需要声明一个输入参数列表,因为它们没有返回值。在这个示例中,Action<string>相当于Func<string, void>。


via:oschina

转载请注明:AspxHtml学习分享网 » C# 的函数编程(Functional programming in C#)

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址