10.1.1避免尾递归的堆栈溢出
对于每一个函数调用,运行时分配一个栈帧(stack frame)。这些帧保存在由系统维护的栈中;调用完成,栈帧被删除;如果函数调用其他函数,那么,一个新的帧添加到这个栈的顶部。栈的大小是有限的,所以,太多的嵌套函数调用会耗光了给其他栈帧的空间,就不能再调用下一个函数了。在 .NET 中发生这种情况时,会引发 StackOverflowException 错...
分类:
其他好文 时间:
2014-12-17 18:40:28
阅读次数:
206
第十章数据结构的效率
本章介绍
■优化和改进递归函数
■使用尾递归(tail-recursion)和连续(continuations)
■高效地使用列表和数组
到目前为止,,我们在本书中已经使用过的函数式方法,有递归和函数式数据结构,比如,不可变列表。我们能写的最简单代码,是使用基本的 F# 集合类型(列表),直接表达我们的意图。在很多情况下,这种方法是合适的;但是,用来处...
分类:
其他好文 时间:
2014-12-16 17:14:48
阅读次数:
133
10.1 优化函数
在前面的章节中,我们已经知道,递归是 F# 中处理函数的主要控制流机制。我们第一次是使用它写一些进行计算的简单函数,例如,计算指定范围内的数字的和或阶乘。后来,我们发现它在处理递归数据结构,最重要的列表是时,是无价的。
我们知道,递归也有一些局限性,堆栈溢出的可能性是最明显的一个;我们将会看到,某些递归计算非常低效。在命令式语言中,通常使用非递归函数,以避免出现问题;...
分类:
其他好文 时间:
2014-12-16 17:10:26
阅读次数:
179
9.5.2 使用值和委托
在这一节,我们要讨论在C# 中使用两个更典型的 F# 构造,如何导出值和高阶函数,后者是棘手的,因为,对于函数,F# 使用相当复杂的内部表示。
如果函数的参数为 int -> int –> int,C# 开发人员会把它看成FastFunc>。使用这种类型虽然是可行的,但非常不方便,我们要使用另一种方法。如果要让高阶函数能在 C# 中使用,可以使用标准的 .NET...
分类:
其他好文 时间:
2014-12-16 10:08:33
阅读次数:
138
9.6 第九章小结
在前面几章,我们讨论了函数式编程,用函数风格实现了几个示例应用程序。我们从简单的函数概念入手,比如,把值组合成“多值(multiple values)”或“可选值(“alternative values)”,然后,讨论了使用函数的方法。在第七章和第八章,我们讨论了函数式程序设计,这不是偶然的决定:本书的结构对应于 F# 的迭代式开发风格。我们从简单的概念开始,能够简单、...
分类:
其他好文 时间:
2014-12-16 10:03:22
阅读次数:
133
9.5.1 处理记录和成员
我们先从一个基本的例子开始。在本章的第一节,我们已经知道如何为表示矩形的 Rect 类型添加成员。现在,我们要在 C# 中使用这个类型。首先,我们需要创建一个新的 F# 库项目,添加源文件(例如,export.fs),代码在清单 9.20。
清单 9.20 把 F# 类型编译成库(F#)
namespace Chapter09.FSharpExp...
分类:
其他好文 时间:
2014-12-15 15:26:03
阅读次数:
155
9.5 在 C# 中使用 F# 库
像 C# 一样,F# 也是一种静态类型的语言,就是说,编译器知道每个值的类型,以及类方法和属性的签名。对于与 C# 的互操作性来说,这是非常重要的,因为,编译器可以生成代码,看起来就像普通的 .NET 库。
与其他 .NET 语言的互操作性
F# 和 C# 或 VB.NET 之间的互操作性是非常平滑的,相比有 .NET 实现的动态类型的语...
1、字符串转换Query String模块的基本介绍Query String模块用于实现URL参数字符串与参数对象之间的互相转换,提供了“stringify”、“parse”等一些实用函数来针对字符串进行处理,通过序列化和反序列化,来更好的应对实际开发中的条件需求,对于逻辑的处理也提供了很好的帮助,...
分类:
Web程序 时间:
2014-12-14 01:52:33
阅读次数:
173
9.4.2.2 F# 中的向上转换和向下转换(UPCASTSAND DOWNCASTS)
如果类型之间的转换不会失败,就称为向上转换(upcast)。我们已经看到,把类型转换成由该类型实现的接口,就是这种情况;另一个示例是把派生类转换成它的基类,在这种情况下,编译器也可以保证操作是正确的,不会失败。
如果有一个基本类型的值,希望将它转换为继承类,操作可能会失败,因为基类的值可能是目标类的...
分类:
其他好文 时间:
2014-12-12 19:14:21
阅读次数:
170
9.4.2 实现接口和类型转换
我们已经讨论过在 F# 中如何声明接口,如何使用对象表达式,创建实现接口的值。这是一个非常轻量级的解决方案,类似于 lambda 函数。正如 lambda 语法,对于创建函数来说,并不总是合适的选择一样,有时,在命名类中实现接口,是有道理的。
我们将继续使用在本章前面的示例,来看一下用 C# 和 F# 实现接口,我们回顾一下两种语言中的接口声明:
...
分类:
其他好文 时间:
2014-12-12 16:47:52
阅读次数:
170