函数
文章平均质量分 57
心想才事成
这个作者很懒,什么都没留下…
展开
-
6.7.3.1 在 C# 中实现 fold
6.7.3.1 在 C# 中实现 fold与 fold 有相同行为的操作,在 .NET 库中也有,但是,名字叫Aggregate(聚合)。通常,它是能够在任何集合类型上运行的扩展方法,我们也可以像 F# 函数一样使用它。清单 6.21 是我们用 C# 3.0 重写前面示例的代码。在 F# 中,我们用元组来保存在聚合过程中的状态。你也许还记得以前的几章中,我们曾提到过,C# 3.0 中的翻译 2014-11-19 15:46:12 · 1168 阅读 · 0 评论 -
5.5 函数值
5.5 函数值 我们已经看到过把函数当作值使用的示例(第三章),当时,写过一个汇总列表元素的函数,把其他的函数作为参数值。用这种方式,我们能够把同一个汇总函数,用于不同的目的:我们先用它来计算列表中所有元素的和,后面用来找出集合中的最大元素。处理数据集合可能是展示函数作为值使用之重要的最佳方式。必须要说的是,这个概念的重要性,远不止这种情况,在本书的其余部分将会逐步看到。我们首先来看一翻译 2014-10-23 16:35:43 · 650 阅读 · 0 评论 -
5.4.4 写泛型函数
5.4.4 写泛型函数 能处理泛型类型的大多数函数或方法都是高阶的(higher order),就是说,它们取其他函数作为参数值。这是一个非常重要的主题,我们会专门用一整章(第六章)来讨论,但我们在还没有进入高阶领域时,就已经可以写泛型函数了。我们准备创建的函数,参数为选项类型,返回包含的值;如果选项类型不包含值,函数将触发异常。我们可以先看一下 C# 版本: T ReadValu翻译 2014-10-23 13:56:13 · 660 阅读 · 0 评论 -
5.4.4 写泛型函数
5.4.4 写泛型函数 能处理泛型类型的大多数函数或方法都是高阶的(higher order),就是说,它们取其他函数作为参数值。这是一个非常重要的主题,我们会专门用一整章(第六章)来讨论,但我们在还没有进入高阶领域时,就已经可以写泛型函数了。我们准备创建的函数,参数为选项类型,返回包含的值;如果选项类型不包含值,函数将触发异常。我们可以先看一下 C# 版本: T ReadValu翻译 2014-10-23 14:04:14 · 483 阅读 · 0 评论 -
5.5.1 Lambda 函数
5.5.1 Lambda 函数 在 F# 中,lambda 函数创建的函数,与一般使用 let 绑定的声明相同。在 C# 中,没有任何内置函数的概念,因此,使用方法,或者委托,写的 lambda 函数,被转换为委托或表达式树(在补充材料“C# 中从委托到函数”中,有表达式树的详细内容),但是,在 C# 中,不能使用 lambda 函数声明普通方法;委托的使用,像任何其他值一样,因此,可以作翻译 2014-10-24 09:38:36 · 601 阅读 · 0 评论 -
3.4.1.1 在 C# 中传递函数作为参数值
3.4.1 处理数字列表假设我们想写一个类似于 SumList 的方法,但是把加法改成乘法。这个修改看起来很简单:可以复制 SumList 方法,然后进行修改。其中只有两个变化:int MultiplyList(FuncList numbers) { if (numbers.IsEmpty) return 1; [1] else return number翻译 2014-09-28 17:59:08 · 6917 阅读 · 0 评论 -
3.4 函数也是值
3.4 函数也是值 在前一节中,我们讨论了不可变列表,学习了以递归方式处理列表。在本节,我们将看到函数编程中的另一个更重要概念:函数也是值。我们将看到这种方式使用函数,为什么如此有用,以及函数也是值到底意谓着什么。更多有关函数的内容将在第五章介绍。翻译 2014-09-28 11:27:25 · 652 阅读 · 0 评论 -
2.3.2 高阶函数(Higher-order functions)
2.3.2 高阶函数(Higher-orderfunctions)[ 关于 parameter 和 argument 一般来说,parameter 常称为形参,更多地类似于变量名称,译为参数;argument 称为实参,则类似于变量的具体值,译为参数值。但是,好像作者有时也未完全区分。因此,在不引起混淆的情况下,都译为参数。] 你已经知道,函数可以视为值,也可以编写一翻译 2014-08-29 15:39:55 · 1074 阅读 · 0 评论 -
3.1.2.2 嵌套函数声明(NESTED FUNCTION DECLARATIONS)
3.1.2.2 嵌套函数声明(NESTEDFUNCTION DECLARATIONS) 我们现在再看一个稍微复杂的函数声明,清单 3.3 演示了 let 绑定的另一个重要方面:嵌套。 清单 3.3 嵌套的 let 绑定 (F# Interactive) > let printSquares message num1 num2 = let printSquareUtili翻译 2014-09-11 19:56:44 · 914 阅读 · 0 评论 -
2.3.1 函数也是值
2.3.1 函数也是值这一节是源于问题,“我们如何把每次使用的不同功能从递归性质的代码中分离出来,而递归的代码始终保持不变?”答案很简单:把递归部分写成一个带参数的函数,由这些参数指定函数应该执行的“唯一操作”。我们还用 SumNumbers 方法来演示。在 2.2.3 节,我们写了一个函数,它取一个起始值,在指定的数值范围内循环,用前面的状态,和这个范围内当前的数进行计算,计算出翻译 2014-08-28 17:07:01 · 610 阅读 · 0 评论 -
3.1.2 函数的声明
3.1.2 函数的声明 正如我们在前面提到的,可以使用 let 绑定声明函数。我们用一个相当简单的函数来演示,实现两个参数的相乘。只要在 F# Interactive 中输入: > let multiply num1 num2 = num1 * num2;; val multiply : int -> int –> int 函数声明,必须在符号名的后面跟一个或多个参翻译 2014-09-10 21:03:59 · 615 阅读 · 0 评论 -
5.5.2.1 函数作为参数值和返回值
5.5.2.1 函数作为参数值和返回值 在第三章,我们已使用过,在 C# 和 F# 中把函数作为参数值,因此,这些基本概念不应该是新的;然而,我们还没有以这种方式使用过 lambda 函数。Lambda 函数是把函数写成另外函数的参数值的最简单方法。清单 5.17 提供了一个简单的示例。在清单中前面的函数,参数为一个数和一个函数,两次调用这个函数,第一次调用的结果作为第二次调用的参数值。翻译 2014-10-24 14:51:32 · 1079 阅读 · 0 评论 -
5.5.3 多参数函数
5.5.3 多参数函数 我们回顾一下,写函数时的选项。在 F# 中,当写的函数有多个参数时,可以使用元组。下一个示例以这种风格写的函数,计算两个整数的和;我们将使用 lambda 函数语法,但在 F# 中,也可以使用简单的 let 绑定,得到同样的结果: > let add = fun (a, b) -> a + b;;val add : int * int -> int翻译 2014-10-24 19:22:06 · 786 阅读 · 0 评论 -
6.1.2.2 F# 的管道运算符
6.1.2.2 F# 的管道运算符 使用管道运算符(|>),能够把函数的第一个参数写在左边,即,在函数名的前面。这是非常有用的,比如,想调用几个函数,处理序列中的值,想要找出第一个处理的值。下面的示例演示了反转 F# 列表,然后,得到一个元素: List.hd(List.rev [1 .. 5]) 这种写法并不优雅,因为,写的操作顺序与执行的顺序相反,且要处理的值在右边,括翻译 2014-10-28 15:04:33 · 1911 阅读 · 0 评论 -
6.1.1 F# 中的泛型函数
6.1.1 F# 中的泛型函数 在第五章,我们看过一个简单的泛型函数,它只有一个泛型选项类型的参数。清单 6.1 是用F# 实现CondPrint 方法的,来自"在函数式编程和面向对象中的泛型代码"侧边栏。它有三个参数值:一个值、一个函数,用于测试是否应打印这个值,还有一个函数,用于设置格式化这个值。 清单 6.1 泛型函数 condPrint (F# Interactive)翻译 2014-10-28 11:13:13 · 785 阅读 · 0 评论 -
6.1.2 自定义运算符
6.1.2 自定义运算符 自定义运算符的方式类似于函数,使用 let 绑定,可以使用任何字符,既可以是通常的 F# 数学运算符(+/-* 清单 6.2 使用自定义运算符处理字符串 (F# Interactive)> let (+>) a b = a + "\n>>" + b;;val ( +> ) : string -> string –>string > prin翻译 2014-10-28 14:14:22 · 1672 阅读 · 0 评论 -
5.5.3.1 散函数应用(PARTIAL FUNCTION APPLICATION)
5.5.3.1 散函数应用(PARTIALFUNCTION APPLICATION) 要展示对函数的这种新理解情况,非常重要,让我们把注意力返回到列表。假设有一个数字列表,我们想要给列表中的每个数字都加上 10。在 F# 中,可使用 List.map 函数完成;在 C# 中,可以使用 LINQ 中的 Select 方法: list.Select(n => n + 10) ß C#翻译 2014-10-24 20:08:03 · 781 阅读 · 0 评论 -
4.2.1 加载和解析数据
4.2.1 加载和解析数据 作为第一步,我们将实现一个函数 convertDataRow,从 CSV 文件中取一行作为字符串,把这一行拆成两部分,以元组形式返回。函数实现后,就可以立即进行测试,输入一个样本(字符串"Test reading,1234”),应该能够正确解析。清单 4.2 是函数的代码和测试结果。 清单 4.2 解析 CSV 文件的一行 (F# Interactive翻译 2014-10-09 17:20:39 · 731 阅读 · 0 评论 -
5.5.2 函数类型
5.5.2 函数类型 我们已经看到,在 F# 中,用箭头符号写函数值的类型,这在很多方面类似于构造元组的方式。早些时候,我们看到过,可以使用带类星号(int * string)的类型构造器,从其他简单类型,构造出元组类型。构造函数类型的方法类似,只是使用函数类型构造器(int -> string)。在数学意义上,函数就是描述每个可能的输入和返回值之间的关系,因此,不需要指定大量的关系的所有翻译 2014-10-24 11:24:06 · 596 阅读 · 0 评论 -
6.5 使用函数
6.5 使用函数 目前为止,我们在这一章中讨论到的所有高阶函数都有类似结构,有两个参数:一个是要处理的值,另一个是指定如何处理这个值的函数。在使用函数时,值参数也可以是函数,因此,高阶函数的两个参数都可以是函数。翻译 2014-11-11 16:23:37 · 722 阅读 · 0 评论 -
3.4.1.2 在 F# 中传递函数作为参数值
3.4.1.2 在 F# 中传递函数作为参数值 在 F# 中的函数 aggregateList 非常类似于我们已经实现的方法,但有一点重要的区别,F# 天然支持把函数作为参数值传递给其他函数,因此,不需要使用委托。在 F# 中,函数是特殊类型。类似于元组,函数的类型是由其他的基本类型构成。元组类型的代码表示,在元素的类型之间使用星号(例如,int * string);而函数的类型表示,翻译 2014-09-29 09:53:56 · 1039 阅读 · 0 评论 -
3.4.2 参数化函数的好处
3.4.2 参数化函数的好处 我们看另一个使用这个函数的示例,为了不同的目的,初看起来,完全不同于计算列表元素的和或积。让我们看看,是否能找出最大值: > aggregateList max (-1) [ 4; 1; 5; 2;8; 3 ];; val it : int = 8 作为第一个参数的函数(max),是内置的 F# 函数,返回给定的两个参数中大的。我们用-1翻译 2014-09-29 11:42:06 · 1433 阅读 · 0 评论 -
6.5.1 函数组合
6.5.1 函数组合 处理函数最重要的操作,就是组合。先看一个示例是非常有用的,这个示例用元组保存(城市的)名字和人口。在清单 6.16 中,我们创建一个函数,根据人口的规模,确定是城市、镇,还是村;同时用保存在列表中的几个地方测试确定状态。 清单 6.16 处理城市信息 (F# Interactive)> let places = [("Grantchester", 552)翻译 2014-11-11 18:48:15 · 1117 阅读 · 0 评论 -
3.1.2.1 函数签名(FUNCTION SIGNATURES)
3.1.2.1 函数签名(FUNCTION SIGNATURES) 在前面示例中,我们还有一部分尚未讨论,即,F# Interactive 的输出,它告诉我们声明了一个新值,和推导出的类型。因为,我们声明的是函数,函数类型写作 int-> int-> int。这个类型表示函数有两个整型参数(在最后箭头符号前有两个 int),返回的结果是整型(在最后箭头符号后的类型)。我们已经知道,F# 使翻译 2014-09-10 21:18:03 · 1350 阅读 · 0 评论 -
F# 中没有内置的 max 函数
F# 中没有内置的 max 函数 比如,我想产生 0.1 至 1 秒的延迟:System.Threading.Thread.Sleep ( [rnd.Next(1000);100] |> List.max)原创 2012-08-02 15:41:14 · 705 阅读 · 0 评论 -
6.2.1 使用函数处理元组
6.2.1 使用函数处理元组 在第 3 章,我们用元组来表示城市和人口。当我们想要增加人口时,不得不写点东西,像这样: let (name, population) = oldPrague let newPrague = (name, population + 13195) 这很清晰,但有点罗唆。第一行分解元组,第二行对第二个元素执行计算,然后,生成新的翻译 2011-05-09 21:13:00 · 450 阅读 · 0 评论 -
6.9 第六章小结
6.9 第六章小结 这一章连同第 5 章一起,讨论了函数值。正如我们在前一章看到的,对于控制程序流,值是重要的,我们能够以函数方式写代码,组合函数,取值作为参数,并返回值作为结果。在这一章中,我们看到更简便方法处理值的。不直接使用值的结构,使用一组在 F# 库中定义的高阶函数值。我们已经看它们是如何实现的,以及如何为我们自己的类型,以实现类似的功能。 特别是,我们讨论了函翻译 2011-05-24 19:00:00 · 414 阅读 · 0 评论 -
6.1 泛型高阶函数
6.1 泛型高阶函数 高阶函数是写泛型函数代码的一种方法,这意味着,相同的代码可重复使用于许多类似但不同的目的。这是现代编程的一个关键,因为,它允许我们写更少的代码行,通过分解出计算的共同部分。 在函数式编程和面向对象中的泛型代码 当编写泛型代码时,通常要对我们所获得的值执行某个操作,但是,由于代码应该是泛型的,我们不想太多地限制值的类型,想要允许代码进一步翻译 2011-05-05 15:37:00 · 530 阅读 · 0 评论 -
6 使用高阶函数处理值
6 使用高阶函数处理值 本章介绍■ 使用元组选项和列表■ 为类型写高阶函数■ 在 F# 中使用自动泛型化■ 组合函数与偏应用 在前面的章节中,我们介绍了最常用的函数值。你已经看到这些值如何被构造,以及如何使用模式匹配来处理它们。像这样显式表示所有逻辑可能是冗长乏味的,特别是如果这个类型具有复杂的结构。 由一个或几个简单值组成的值的类型包括前一翻译 2011-05-05 14:57:00 · 520 阅读 · 0 评论 -
6.1.1 写 F# 中的泛型函数
6.1.1 写 F# 中的泛型函数 在第 5 章,我们看到了一个简单的泛型函数,它只使用单个参数值,是一个泛型选项类型。清单 6.1 显示 CondPrint 方法的 F# 实现,来自"在函数式编程和面向对象中的泛型代码"侧边栏。它有三个参数值:一个值、一个函数,用于 测试是否应打印这个值,还有一个函数,用于设置格式化这个值。 Listing 6.1 Generic fun翻译 2011-05-06 14:47:00 · 668 阅读 · 0 评论 -
6.4.1 使用 map 函数
6.4.1 使用 map 函数 我们将使用的两个操作,已在 F# 库中可用了,因此,我们首先看一下如何使用它们。稍后,我们将讨论它们的实现,以及如何从 C# 中使用它们。正如我们已经看到的,要了解函数在 F# 做什么的最好方法,通常是了解它的类型签名。让我们来看一下 Option.map: > Option.map;; val it : (('a -> 'b) -> '翻译 2011-05-12 09:14:00 · 496 阅读 · 0 评论 -
6.5 处理函数
6.5 处理函数 目前为止,我们在这一章中讨论到的所有高阶函数都有类似结构。它们有两个参数:一个是要处理的值,另一个是函数,指定如何处理这个值。在处理函数时,值参数也可以是一个函数,所以,我们的高阶函数,将取两个函数作为参数值。翻译 2011-05-16 11:34:00 · 371 阅读 · 0 评论 -
6.5.1 函数组合
6.5.1 函数组合 处理函数最重要的操作,就是组合。让我们首先看一个示例,这是非常有用的。我们将使用这个示例,用元组存储(城市的)名字和人口。在清单 6.16 中,我们创建一个函数,根据人口的规模,确定是城市、镇,还是村。还通过确定存储在列表中的几个地方的状态测试它。 Listing 6.16 Working with city information (F# Inter翻译 2011-05-17 11:37:00 · 606 阅读 · 0 评论 -
6.5.2 C# 中的函数组合
6.5.2 C# 中的函数组合 C# 中的函数组合是可能的,但它的使用非常有限。这是部分是由于在 C# 中,偏应用不能很容易使用,但更重要的是,因为大多数操作是写为成员,而不是函数。我们至少可以在 C# 中演示同样的想法。清单 6.18 显示了 Compose 方法的实现,以及使用它的示例。 Listing 6.18 Implementing and using the C翻译 2011-05-17 14:48:00 · 541 阅读 · 0 评论 -
8.1.2 在 C# 中把行为表示成函数
8.1.2 在 C# 中把行为表示成函数 我们前面提到过,以面向对象的方式理解函数,就是把它认为是有一个单独方法的接口。如果我们看一下清单 8.1 的代码,可以看到 IClientTest 就是这样声明的。这意味着,这个测试可以很容易地表示成一个简单的函数。在 C# 中,我们可以使用 lambda 函数来写测试: Func isRiskyYearsInJob = c翻译 2011-06-20 16:52:00 · 553 阅读 · 0 评论 -
14.2.5 并行化应用程序
14.2.5 并行化应用程序 因为这一章是真正有关并行化的,这才是这个应用程序中的最有趣的部分。我们将讨论两种语言写的代码,首先以可能最简单的方法实现 C# 版本。 在 C# 中以并行方式运行滤镜 要实现 C# 版本,我们从清单 14.11 中把 RunFilter 方法拿过来,把 for 循环替换成对 Par翻译 2011-12-06 12:16:52 · 618 阅读 · 0 评论 -
15.3.2 将函数应用到行为
15.3.2 将函数应用到行为 在早先描述行为时,我们解释过,行为是一个复合值,相似性在于 Behavior 和 Option 之间。两者都是包含另一个值的复合值,但有不同的方式。选项类型的不寻常,在于它可能为空,而行为的不寻常,在于值依时间而变。 这个比喻表明行为的方向。我们已经看到,Option.map 在几个不同的上下文中,指定的函数应用到由该选项携带的翻译 2011-12-18 10:52:08 · 640 阅读 · 0 评论 -
8.1.4 在 F# 中使用函数列表
8.1.4 在 F# 中使用函数列表 首先,我们声明一个表示有关客户信息的类型。客户端有相当多属性,所以,最自然的表示将是 F# 的记录类型,我们在前一章中已经看过。清单 8.4 显示了这个类型声明,和所创建的示例客户的代码。 Listing 8.4 Client record type and sample value (F# Interactive) > typ翻译 2011-06-21 14:46:00 · 541 阅读 · 0 评论 -
4.5 第四章小结
4.5 第四章小结 在这一章中,我们开发了一个简单但实用的应用程序,绘制饼图。我们讨论了基本的 F# 和 .NET 的数字数据类型,探讨了 F# 和 .NET 两个使用字符串的函数。此外,我们还演示了如何从 F# 中使用普通的 .NET 库,也看到了使用 Windows Forms,System.Drawing 以及基本的 I/O 的例子。 我们想在这一章中演示的是一个典翻译 2011-04-13 20:00:00 · 307 阅读 · 0 评论 -
7.5.2 使用访问者模式添加函数
7.5.2 使用访问者模式添加函数 在已有的数据结构上添加新的操作,是函数语言中实现处理数据的任何代码的主要方式。在面向对象的语言,很难做到,也很少需要。在这一节,为此目的,我们将讨访问者模式,将草绘如何,使用它在我们的文档表示中添加操作。图 7.8 显示的是我们在这一节要用到的基类。 图 7.8 表示文档的类层次,和泛型访问者类,状态作为泛型类型参数 (T);由于 A翻译 2011-06-17 17:27:00 · 545 阅读 · 0 评论