实用函数编程
文章平均质量分 54
心想才事成
这个作者很懒,什么都没留下…
展开
-
感谢
感谢 “蝴蝶效应(butterfly effect)”,是由Edward Lorenz 提出的一个概念,是基于混沌理论:是说表面上看来很小的事件有可能引起很大的事件,比如,蝴蝶在亚洲的某个地方轻轻扇了几下翅膀,就可能引起南美洲的飓风。(蝴蝶扇动翅膀在理论上是恒定的,但是地点(亚洲或巴西)和结果(飓风或龙卷风)却会不同)。这足以说明,正是由于有这许多人(和蝴蝶),才有可能有了这本书,如果没有翻译 2014-07-16 22:45:02 · 752 阅读 · 0 评论 -
关于本书
关于本书 如果你已经开发过 .NET 程序,熟悉面向对象技术,想知道“函数式编程”有什么新内容,以及我们如何能从中受益,那么,本书肯定适合你。本书特别适合已经有面向对象编程和 C# 2.0 知识的开发人员,当然,通常并不要求你有函数编程的知识,更不要求知道 F#。事实上,如果你过去常用面向对象方式思考问题,那么,学习函数式编程会更困难,因为许多函数式思想对你来说是陌生的。我们写这本书已翻译 2014-07-16 22:45:50 · 882 阅读 · 0 评论 -
第一部分 学习函数式思维
第一部分学习函数式思维 捡起这本书的原因可能很多。可能是在学习 LINQ 和 C# 3.0,或者受此影响的别的技术时,听到过函数式编程,你想知道它是否有还其他意思;也可能听说过函数式编程可以使写并行或异步程序更容易;也许听说过函数风格的其他有趣应用,比如,如何写出没有可变状态的程序;还可能已听说过一种叫 F# 的新语言,将会成为 Visual Studio 2010 的一部分,你可能想知道翻译 2014-07-17 17:38:43 · 916 阅读 · 0 评论 -
第一章 不同的思维
第一章不同的思维 本章介绍■理解函数式编程■用函数式思想提高生产力■写出阵高效、可读性强的代码■实现第一个 F# 应用程序 函数语言非常富于表达,能用短小、简洁、具可读性的代码,实现强大的功能。之所有这些是可能的,是因为函数语言提供了更加丰富的方式,来表达抽象的概念。我们可以隐藏代码是“如何”执行的,只要指出所需的“结果”,并且这样的(指出如何实现结果)代码只要写翻译 2014-07-17 18:03:04 · 804 阅读 · 0 评论 -
关于封面
关于封面 实用函数编程(Real-World Functional Programming)封面上的图片采用“一个雇员”最先它有这个本快的事情(,展示的是一个职员或公务员,穿着优雅,戴大礼帽,夹着雨伞。这个插图是 19 世纪法国出版的Sylvain Maréchal 的四卷本区域穿着习惯,其中每一幅图都绘得很精细,并手工着色。Maréchal 丰富多彩的收藏使我们想就在 200 年前,世界翻译 2014-07-16 22:48:53 · 1045 阅读 · 0 评论 -
1.1 什么是函数式编程?
1.1 什么是函数式编程? 想给函数式编程下个明确的定义,是困难的。因为,存在不同的函数语言,但是,并没有明确的、每种函数语言必须具有的特征集。尽管如此,函数语言仍有一些共同的属性,只是表达解决编程问题的风格稍微有点不同。最容易地描述函数式编程,就是把它与最常见的编程风格:命令式编程(imperative programming),进行比较。 [函数语言]函数式编程的编程风格是翻译 2014-07-18 16:00:58 · 2896 阅读 · 0 评论 -
1.2 通往实用函数编程之路
1.2 通往实用函数编程之路 函数式编程的思想发源要早于第一台计算机,其历史可追溯到上世纪三十年代,当时 Alonzo Church 和 Stephen C. Kleene 引入一种理论,叫 lambda 演算,属于数学基础研究。虽然它未能实现其初衷,但仍有一些逻辑分支在使用,并发展出有用计算理论。为了学习函数式编程的基本原理,有必须简单了解一下lambda 演算(下一章)。发明计算机以后翻译 2014-07-18 21:06:00 · 965 阅读 · 0 评论 -
1.3.4 设计并发友好的应用程序
1.3.4 设计并发友好的应用程序 使用传统的命令风格编写多线程应用程序时,我们要面对两个问题:■很难让现有的顺序代码变成并行的代码,因为要显式使用线程,必须修改大部分的基本代码。■使用共享状态和锁定是困难的。必须仔细考虑如何使用锁来避免争用条件和死锁,留下足够的空间并行执行。函数式编程给了我们答案:■使用声明编式程风格时,可以在现有的代码中引入并行。替换很少几个基元,就能翻译 2014-07-22 18:03:46 · 1214 阅读 · 0 评论 -
1.3 用函数式编程提高生产力
1.3 用函数式编程提高生产力 很多人觉得函数式编程优雅或甚至是漂亮,但这很难成为在商业环境中使用的一个好理由。优雅不能当钞票,真的不幸。用函数风格编程的主要原因是让你和你的团队工作更高效。在本节,我们将看到函数式编程带来的主要优势,解释它是如何解决一些现代软件开发最重要问题的。在探索具体的好处之前,我们先宏观地来看一下。函数式编程并未严格界定,因为函数式思想可以有不同的形式。翻译 2014-07-22 10:57:13 · 1010 阅读 · 0 评论 -
1.3.1 函数范式
1.3.1 函数范式 函数式编程是一种编程范式,它定义了我们在思考问题时可以使用的概念,但它不能精确地指定如何用编程语言来表达这些概念。因此,就有了许多函数语言,每一种语言强调了函数风格不同方面和特征。我们可以用一种比较熟悉的范式,面向对象编程(object-oriented programming,OOP)来类比。在面向对象的风格中,我们思考问题是以对象为出发点。每一种面向对象的语言翻译 2014-07-22 11:23:15 · 1923 阅读 · 0 评论 -
1.3.2 声明式编程风格
1.3.2 声明式编程风格 用声明式编程风格,我们表达的程序逻辑无需说明执行细节。这个描述听起来有些耳熟,因为它十分类似于我们在 1.1 节中看到的函数式编程的定义。但声明式编程是更为一般的概念,可以使用不同技术来实现;函数式编程只是实现这一目标的一种方法。我们看一个演示,如何用函数语言编写声明性代码。我们写程序,要以计算机所理解的词汇,向它解释我们的目标,在命令式语言中,这由命令组成翻译 2014-07-22 16:17:48 · 1435 阅读 · 0 评论 -
1.3.3 了解程序的运行
1.3.3 了解程序的运行 在通常的命令式风格中,程序由对象组成,对象有内部状态,既可以经直接更改,也可以通过调用对象的方法更改。这意味着当我们调用一个方法时,很难知道这个操作影响了哪个状态。例如,在清单 1.1 的C# 代码片段中,我们创建了一个椭圆,获取它的边框,在返回的矩形上调用方法,最后,返回这个椭圆给调用者。 Listing 1.1 Working with ellips翻译 2014-07-22 16:21:19 · 910 阅读 · 0 评论 -
1.4 函数式编程示例
1.4 函数式编程示例 下面的这些示例表明,函数式编程并不是任何意义上的理论学科,你会发现,甚至可能通过现有的 .NET 方法,应用了一些函数式思想。阅读有关函数式编程的内容,将有助于更深层次地理解这些技术,并高效地使用。在这书的后面,我们还将通过一些示例来展示函数式风格重要的实际好处。在第一组示例中,我们将探讨声明式编程。翻译 2014-07-23 15:46:04 · 789 阅读 · 0 评论 -
1.3.5 函数风格如何形成代码
1.3.5 函数风格如何形成代码 函数式编程范式无疑会对设计和实现应用程序产生影响,但是,这并不意味着一切要从头开始,因为今天正在使用的许多编程原则,同样适用于函数式应用程序,特别是在设计层,如何组织应用程序方面,尤其如此。函数式编程在实现层可能彻底改变了解决问题的方法。当然,学习使用函数式编程思想,不必马上就实现彻底改变。在 C# 中学到有效使用方法,在 F# 中,对等效的结构同样适翻译 2014-07-23 15:28:43 · 916 阅读 · 0 评论 -
1.4.1 用声明式风格表达意图
1.4.1 用声明式风格表达意图 在上一节中,我们介绍了声明式编码风格能够提高生产力,支持声明式的风格编程语言,能够以新的方式组合基本结构。使用这种风格,并不限于基本的语句序列或内置的循环,因此生成的代码更多的是描述了计算机应当做什么,而不是如何去做。我们将泛泛地讨论这种风格,因为其思想是通用的,不依赖任何具体的技术。但是,用大家可能熟悉的示例来演示如何应用则更好。前两个示例将演示 L翻译 2014-07-24 10:40:45 · 926 阅读 · 0 评论 -
1.4.1.1 用 LINQ 处理数据
1.4.1.1 用 LINQ 处理数据 如果你已经在使用 LINQ,那么这个示例只是提醒,但我们会用它来展示一些更重要的内容。这里示例代码处理数据,使用的是标准的命令式编程风格。 Listing 1.3 Imperative data processing (C#) IEnumerablestring>GetExpenisveProducts() { Listst翻译 2014-07-24 11:38:21 · 954 阅读 · 0 评论 -
1.4.1.3 声明式函数动画
1.4.1.3 声明式函数动画 函数式编程能够以声明式风格编写库来解决存在的问题,我们已经看到用 LINQ 处理数据,用WPF 处理用户界面;但在函数式编程中,通常是创建库来解决自己的问域。我们前面提到过,声明式风格可以不考虑实现的细节,遗漏了一些东西。函数式编程没有任何神秘的力量,能为我们实现困难的部分。设计我们自己的库时,需要实现所有的技术细节;只是实现的细节隐藏在库中(就像 LI翻译 2014-07-25 17:01:23 · 968 阅读 · 0 评论 -
1.4.1.2 用 XAML 描述用户界面
1.4.1.2 用 XAML 描述用户界面 Windows 表现层基础库(WindowsPresentation Foundation,WPF)是用于创建用户界面的 .NET 库,这个库支持声明式编程风格,它将描述用户界面部分与实现命令式程序逻辑的部分分隔开来。使用Windows 表现层基础库的最好办法,是使程序逻辑尽可能小,并尽可能多地以声明式方式创建。声明式的描述用树状结构表示,其翻译 2014-07-25 09:35:00 · 1247 阅读 · 0 评论 -
1.4.2 理解使用不可变性的代码
1.4.2 理解使用不可变性的代码 在前面介绍函数式风格的好处时,我们讨论过不可变性(immutability)。我们使用的示例是一个带边框的椭圆,但是代码的具体行为并不清楚。当我们用不可变对象重写了代码以后,它就变得更容易理解。在后面的章节中,我们会回到这个主题并更详细地讨论。此示例的目的是显示在实践中不可变的对象的表现。再次强调,如果你在此时没能全部掌握,也不要担心。想象一下,我们翻译 2014-07-26 14:52:17 · 872 阅读 · 0 评论 -
实用函数编程《序》
序 本书不同于现在的其他编程书籍,它不仅关注某种专门的编程语言或库,而是用目前用目前的编程语言或库去解释思维的方法。思维方法正变得越来越重要,已经重叠许多新的技术。我们已经知道本书中描述的某些概念,因为,函数式思想在许多技术中都有所体现。.NET 的示例包括C# 3.0 和LINQ 项目,微软对 .NET 的并行扩展(Microsoft Parallel Extensions to .翻译 2014-07-09 10:52:11 · 688 阅读 · 0 评论 -
1.4.3.1 并行化不可变程序
1.4.3.1 并行化不可变程序 首先,让我们再看看清单 1.8,这是两段以函数方式写的游戏代码。在第一段,第二行用到了第一行的结果(运动后怪物的状态)。由于使用了不可变类,它没有给我们任何空间引入并行机制。第二段代码的两行是独立的。我们刚才说过,用函数式编程,独立的程序部分能够并行。现在,我们发现,不可变性对于找出哪些部分程序是独立的,是一个好方法。即使我们不知道任何细节,也可以看出翻译 2014-07-28 14:55:57 · 944 阅读 · 0 评论 -
1.4.3 编写有效的并行程序
1.4.3 编写有效的并行程序 函数式编程可以更方便编写并行程序,这可能是你打算阅读这本书的原因。在本节,我们将用几个示例来演示函数式程序如何使并行更容易。在前两个示例中,我们将使用 Parallel Extensions to .NET(.NET 的并行扩展),这是微软的一项新技术,用于编写并行化的应用程序,是 .NET 4.0 的一部分。如你所料,ParallelExtensions翻译 2014-07-28 10:22:24 · 1057 阅读 · 0 评论 -
1.4.2.1 阅读函数式程序
1.4.2.1 阅读函数式程序 我们在清单 1.1 中看过一个示例,就是使用了不可变类型,我们的结论是,不可变类型使代码更具可读性。在本节,我们将考虑两段代码,可以用在我们函数式游戏中。清单 1.8 中有两个示例,都涉及两个游戏角色(player 和 monster)。第一个示例说明怪物[1]如何移动一步,然后,判断玩家是否正处于危险之中,第二示例演示如何射击。 Listing翻译 2014-07-26 22:27:08 · 853 阅读 · 0 评论 -
1.5.1 用 F# 写 Hello world
1.5.1 用 F# 写 Hello world 开始使用 F# 最简单的方法是创建一个新的脚本文件。脚本是轻量级 F# 源文件,它一定属于项目,扩展名通常是 .fsx。在 Visual Studio 中,可以选择 File > New > File (或按 Ctrl + N),从脚本类别中选择 F#脚本文件。有了这个文件之后,我们就可以直接写“Hello world”代码了。 L翻译 2014-08-04 08:36:47 · 1763 阅读 · 0 评论 -
1.4.3.2 使用 PLINQ 的声明式并行
1.4.3.2 使用 PLINQ 的声明式并行 声明式编程风格提供了另一种写并行程序的方法。我们知道,用声明式写代码,就是进行基元组成。在 LINQ 中,这些基元是查询运算符,比如 where 和 select。使用声明式风格,我们可以很容易替换基元的实现,PLINQ 就是这样做的:我们能够用并行的查询运算符替换标准查询运算符。清单 1.9 是一个查询,更新虚拟游戏中的所有怪物,并删除翻译 2014-07-29 08:39:13 · 1027 阅读 · 0 评论 -
1.5.2 从简单到实用
1.5.2 从简单到实用 启动新项目,开头通常不知道到结束时代码会是什么样子,在这个阶段,代码演变很迅速。但随着项目逐渐成熟,架构更加固定,我们更关心的是解决方案的可靠性,而不是灵活性。有趣的是,这些要求并不会反映在我们所使用的编程语言和工具中;而 F# 在工具和语言两方面都很好地体现这些要求,单从这点来看,F# 就有吸引力。 F# 开发过程简介 使用F# 交互式工具,用户翻译 2014-08-05 11:15:27 · 747 阅读 · 0 评论 -
1.5 F# 简介
1.5 F# 简介 书中各个阶段都有 F# 的介绍,只要有必要。在这一节,我们只讨论一些基础知识,会写几个简短的示例,这样,你自己就可以开始体验;第二章,在总结重要的函数概念后,我们会更仔细地讨论 F#;第一个实用的 F# 应用会出现在第四章;讨论了“Hello world”示例后,讲解能用 F# 语言干什么;还将讨论 F#典型的开发过程,因为它和我们用 C# 进行开发的过程可能完全不同。翻译 2014-08-01 15:28:49 · 931 阅读 · 0 评论 -
2.5 第二章小结
2.5 第二章小结 在这一章,我们简要地讨论了有关函数编程的内容,包括 lambda 演算的数学基础;学习了函数编程语言的核心要素,如不可变性,递归,函数当成值使用。我们简要介绍了影响函数语言的设计,并且几乎在所有函数语言中都有一定程度体现的思想。这些思想包括,使语言可扩展,用声明式风格写程序,避免可变状态。虽然我们讨论的所有语言,主体都是“函数式”,但它们之间仍有重要差异,因为每种语言对翻译 2014-09-04 17:51:58 · 593 阅读 · 0 评论 -
1.5.2.1 从简单开始
1.5.2.1 从简单开始 开始新项目,通常新建脚本文件,尝试实现最初的原型,试验关键想法。这时的脚本文件包含了各种试验的源代码,经常是杂乱无章的。如图 1.3,这个阶段的 Visual Studio IDE 可能就像这个样子。图 1.3 使用交互式 F#,先测试代码,然后包装成函数。 图 1.3 只显示了编辑器和 F# 交互窗口,但这就是我们现在所需要的全部,因为我们还没翻译 2014-08-07 17:49:35 · 994 阅读 · 0 评论 -
2.2.3 用递归改变程序状态
2.2.3 用递归改变程序状态 现在,我们来写一此更复杂的函数,看看如何使用值。我们实现的函数,是求指定范围内的数字的和。当然你可以直接计算出和,但我们是把它作为使用循环进行计算的示例。(在 2.3.1 节,我们会把代码改成更通用的函数。) int SumNumbers(int from, int to) { intres = 0; for(int i = from;翻译 2014-08-20 11:14:06 · 843 阅读 · 0 评论 -
2.2.1 使用不可变值
2.2.1 使用不可变值 函数程序第一个常见功能是很少使用典型的变量,这与我们从其他编程语言所了解不同。主要的差别在于,函数语言更喜欢用不可变的变量,即变量值一旦初始化后,就不能改变。因此,再称为“变量”就相当不合适了,函数程序员通常称为“值”。我们用一个示例来说明,说要写一个取初始值的程序,再从控制台读两个数字,将初始值加上第一个数字,再将结果乘上第二个数字。在 C# 中,通常的做翻译 2014-08-19 09:20:07 · 734 阅读 · 0 评论 -
3.2.3 计算元组
3.2.3 计算元组 目前为止,我们还只是用这个示例创建和输出元组,现在,我们要对元组进行一些计算。假设去年增加大量的新生人口,我们就要增加居民人数。我们知道,元组类型是不可变的,因此,不可能设置 C# 元组类的属性。在 F# 中,有两个读元组值的函数(fst 和 snd),也没有设置值的函数,情况是类似的。因此,计算必须遵循通常的函数模式,通过复制初始元组返回新的元组,城市名不变,人翻译 2014-09-18 15:16:46 · 1330 阅读 · 0 评论 -
1.5.2.2 到稳健结束
1.5.2.2 到稳健结束 与许多其他因简单而流行的语言不同,F# 还体现在其他方面,比如,能够写出成熟、稳健而安全的代码。通常的过程是先从简单的代码着手,随着代码库变大再进行一定的重构(refactor),方便其他 F# 开发人员访问,能写出更好的文档,支持与 .NET 和 C# 进行更好的互操作。把功能封装(encapsulate)成 .NET 类,也许便从NET 语言中问的最重要翻译 2014-08-08 17:30:40 · 941 阅读 · 0 评论 -
1.6 小结
1.6 小结 这一章简要概述了函数式编程及其意义。我们介绍了声明式编程风格,可用于以函数风格写应用程序和库函数。声明式编程已有许多成功的应用,如 WPF 和 LINQ,而且,在 C# 3.0 中,能够用它来为其他类型的问题写函数式解决方案。并行编程是现代软件开发展的一大挑战,使用函数方法能使问题显著容易,这要归功于不可变性和声明式编程。不可变性有助于写出正确、安全的代码;声明式编程能够翻译 2014-08-08 17:30:11 · 612 阅读 · 0 评论 -
第三章 F# 和 C# 中元组、列表和函数
第三章 F# 和 C# 中元组、列表和函数 本章介绍■声明函数和值■使用不可变元组和列表■用递归处理列表■函数化处理函数 在第二章,我们从宏观上探讨了函数编程中最重要的概念,除了一些用来说明概念的简单示例之外,没有展示任何实际的函数式代码。到目前为止,我们的目标还是为了说明概念之间的关系,以及对编程来说结果完全不同。在这一章,我们终于开始写函数式的 F# 代码了翻译 2014-09-05 16:11:32 · 897 阅读 · 0 评论 -
3.1 值和函数的声明
3.1 值和函数的声明 我们在第一章已经看到过几个值绑定的示例(在 F# 中用 let 关键字)。正如你将看到的,值绑定不只是值的声明,它是强大而常用的结构,既能声明局部和全局值,还能声明函数。我们在探索F # 中使用函数编程的示例之前,先看看值绑定。翻译 2014-09-07 21:02:37 · 529 阅读 · 0 评论 -
第二章 函数编程的核心概念
第二章函数编程的核心概念 本章介绍■了解概念和基础■不可变数据编程■函数式代码的推论■函数式值和数据类型 如果你问三个函数程序员,什么是函数范式最基本的方面,很可能有三个不同的答案。原因是函数编程已经存在很长时间了,各种不同的编程语言应用范围很广泛;每种语言强调的重点不同,但对于其他的语言来说,可能并不重要;但其中的大部分概念在所有的函数式语言中都有所表现。本章翻译 2014-08-12 09:30:31 · 843 阅读 · 0 评论 -
3.1.1 值的声明和作用域
3.1.1 值的声明和作用域 我们已经知道,可以使用 let 关键字声明不可变值。但尚未讨论值的范围域(scope),不过很容易用一个具体的示例来解释。清单 3.1 非常简单,但是,在这四行代码的后面到底隐藏了多少奥秘,我想你也一定会很惊讶。 清单 3.1 值的作用域 (F#) let number = 42 [1]printfn "%d" numberlet翻译 2014-09-08 11:29:30 · 582 阅读 · 0 评论 -
2.2.4 用表达式代替语句
2.2.4 用表达式代替语句 在命令式语言中,表达式是简单的、可以计算并产生结果的代码块,因此,方法调用、任何布尔值的使用,或者整数运算,都是表达式;而语句是能够影响程序的状态,但没有任何结果的代码块。不返回任何值的方法调用就是语句,因为它会影响程序的状态,而不管方法做了什么;赋值也会更改状态(通过改变变量的值),但在最简单的情况下,它不会返回任何值。 注意 在 C# 中,翻译 2014-08-25 17:05:57 · 1190 阅读 · 0 评论 -
2.2.5 计算 (Computation by calculation)
2.2.5 计算 (Computation bycalculation) [Computation,calculation,都翻成了计算,大概强调的重点不同吧。Computation by calculation,也还是翻成计算吧。evaluate,多数时候也翻译成计算,有时也译成分析。]我们在前两节中讨论了思考有关程序执行的新方法。要了解命令式程序的执行,就必须理解是翻译 2014-08-26 18:03:33 · 2717 阅读 · 0 评论