12.5.4 在 C# 中实现查询运算符
在清单 12.14 中,当我们讨论序列和分析 SelectMany 操作时,已经知道可以把 C# 查询转换为方法调用。我们实现的查询,只支持以 select 子句结尾,而忽视那些仅对集合有用的情况,比如分组,这样,就需要实现 Select 扩展方法。
我们前面说过,第二个和随后的 from 子句会转换成对 SelectMany 方法的调用。当使用...
12.5.3 在 F# 中实现计算生成器
在计算表达式块前面的标识符,是类的实例,把所需的操作实现成为实例成员。许多操作都已经有了,我们根本不必要提供所有的,最基本的操作用 Bind 和 Return 成员实现。当 F# 编译器看到计算表达式,比如清单 12.18 时,会把它转换为使用这些成员的F# 代码。F# 示例转换成这样:
value.Bind(ReadInt(), fun ...
分类:
其他好文 时间:
2015-01-30 17:41:25
阅读次数:
153
12.5.2 写计算
C# 查询表达式和 F# 计算表达式,可以使用函数,行为方式非标准(返回单子值),就好像返回普通值。我们在这一节使用的计算类型是 ValueWrapper ,因此,原始函数将返回值的类型是 ValueWrapper,而不是 T。
实现这些函数,既可以使用其他的查询或计算表达式,也可以通过直接创建计算类型的值。有些计算表达式可以封装复杂的逻辑,所以,直接创建值可能有困...
分类:
其他好文 时间:
2015-01-30 16:08:33
阅读次数:
167
12.5.1 声明计算类型
在这个示例中,计算的类型(在 Haskell 术语中的单子类型)称为 ValueWrapper,它只是存储泛型类型参数T 的值,并不会为类型增加任何其他功能。这就是说,计算只处理标准值,但是,我们能够用 C# 中的查询表达式, F# 中的计算表达式,写代码(来增加功能)。
清单 12.17 显示了在 C# 和 F# 中的类型声明。在 C# 中,我们创建简单的类...
分类:
其他好文 时间:
2015-01-29 17:41:52
阅读次数:
196
12.3.3.3 在 C# 中使用平面映射
类似于 collect 函数的LINQ 运算符,是 SelectMany,但两者之间也有差异,因为 LINQ 有不同的要求。而 F# 序列表达式只能使用 collect 函数表示,LINQ 查询可以使用许多其它运算符,所以,对于序列操作,它们需要不同的方式。
我们再先看一下普通语法,然后,再考虑转换成使用显式扩展方法的语法,我们还使用前面的 F...
12.3.3.2 直接使用平面映射
首先,我们要看看平面映射到底是什么样子。通常,理解函数如何运行的第一步,就是研究类型签名。图 12.2 比较了 Seq.map(普通映射)和 Seq.collect(平面映射)的类型签名。
图 12.2 对于每个输入元素,普通映射返回一个元素,而平面映射,可以返回元素的任意集合。
提醒一下,类型签名中的 # 号,描述映射函数,传递给...
分类:
其他好文 时间:
2015-01-25 18:18:48
阅读次数:
213
12.3.3.1 序列表达式中的平面映射
假设我们有一个关于城市的元组列表,每个元组包含城市的名字和它所在的国家,另外,我们还有一个列表,是用户所选的城市。因此,我们可以这样表示样本数据:
let cities = [ ("New York","USA"); ("London", "UK");
("Cambridge","UK"); ("Ca...
分类:
其他好文 时间:
2015-01-25 11:09:37
阅读次数:
182
12.3.3 平面映射(flatteningprojection)
平面映射,可以为源集合中的每个元素,生成元素序列,合并所有返回序列。我们很快就会看到,这是定义其他处理操作,包括映射和筛选,的基本操作。平面映射所独有的特征,就是能够为每个输入元素生成多个输出元素。
注意
在 LINQ 库中,这个操作称为 SelectMany。在查询表达式中,用多个 from 子句表示。从...
分类:
其他好文 时间:
2015-01-24 11:46:10
阅读次数:
211
12.3.2.2 使用查询和序列表达式
在 C# 3.0 中,我们可以使用新的查询表达式语法,写有关映射和筛选数据的操作。查询表达式还支持许多其他操作,但我们会只关注映射和筛选,来演示函数技术和 F# 功能。
F# 虽然没有专门提供的查询表达式,但是,使用序列表达式,仍可以轻松地写出映射和筛选数据的查询。这是因为序列表达式在 F# 中所有地方都可以使用,而不仅仅是返回序列的函数。清单 1...
分类:
其他好文 时间:
2015-01-23 21:39:30
阅读次数:
290
12.3.2.1 使用高阶函数
在 F# 中,使用 Seq 模块与 List 相同,而且,我们已经知道,如何在 C# 中使用 LINQ 扩展方法。而在使用列表和序列方面,有一个显著区别:序列是延迟的。直到从返回序列中取出元素时,处理代码才执行,尽管那样,它所做的工作,也只是为了返回结果所需要的。现在,我们用简单的代码段来演示一下:
var nums1 =
n...
分类:
其他好文 时间:
2015-01-23 14:43:43
阅读次数:
118