6.6.2 自动泛型化(automatic generalization)

在这一章,我们已经实现了几个 F# 的高阶函数,也看到了在 F# 和 C# 中并排的实现。F# 实现的很重要方面,是我们根本不需要指定类型;这是由于有了自动泛型化(automatic generalization),它用在推断函数声明的类型。我们将用Option.bind 函数的实现作为示例,介绍这个过程是如何工作方法的:

let bind func value =   [1]

match value with    [2]

|None –> None     [3]

|Some(a) -> func(a)  [4]

1、我们将一步一步地描述这个函数的类型推断过程。从最通用的可能类型开始,在处理代码中增加约束,这样,可以在清单中看到处理函数体时的过程。

2、使用声明签名[1]推断出 bind 是有两个参数的函数,为每个参数值和返回类型分配新的类型参数:

func : ‘t1

value : ‘t2

bind : ‘t1 -> ‘t2 -> ‘t3

3、使用模式匹配[2]推断出 value 是选项类型,因为,它是依据Some 和 None 模式进行匹配的。使用[3]推断出bind 的结果也是选项类型,因为,它可能有 None 值:

func : ‘t1

value : option<‘t4>

bind : ‘t1 -> option<‘t4> ->option<‘t5>

4、使用[4]推断出 func 是函数,因为我们将用一个参数去调用:

func : (‘t6 -> ‘t7)

value : option<‘t4>

bind : (‘t6 -> ‘t7) ->option<‘t4> -> option<‘t5>

5、 从[4]我们知道,函数的参数类型‘t4,与 bind 函数结果的类型相同,这样,我们可以添加下面两个约束:

‘t6 = ‘t4

‘t7 = option<‘t5>

6、现在,我们可使用在上一步得到的约束,来替换类型 ‘t6 和 ‘t7 :

func : (‘t4 -> option<‘t5>)

value : option<‘t4>

bind : (‘t4 -> option<‘t5>) ->option<‘t4> -> option<‘t5>

7、我们用 F# 的通常标准重新命名类型参数:

bind : (‘a -> option<‘b>) ->option<‘a> -> option<‘b>

虽然,使用这种描述实现 F# 类型推断算法是困难的,但它能够在推断高阶函数的类型时,了F# 可以使用何种信息。在这个过程中最有重要的步骤,可能是推断用作参数的函数(func)类型;这个步骤之所以重要,是因为作为参数的函数表示能够在在值上进行的操作。正如我们早些时候所见的,在某种意义上,这类似于方法,但由于有了类型推断,在 F# 中写这样的代码,不需要任何额外的类型说明,而且代码还是完全类型安全的。

有关类型推断与自动泛型化的简短插曲之后,我们还要回到如何编写和使用高阶函数上来。在第五章,我们已经讨论了大部分类型,但仍缺少一个重要的函数式值类型;在下一节,我们将通过高阶函数处理列表,解决更熟悉的领域的问题。

时间: 2024-10-22 12:00:42

6.6.2 自动泛型化(automatic generalization)的相关文章

cvThreshold与cvAdaptiveThreshold 阀值化操作与自动阀值化操作

核心函数:cvThreshold,cvAdaptiveThreshold 程序: 代码: #include "cv.h" #include "cxcore.h" #include "highgui.h" #include <iostream> int AdaptiveThreshold(int argc,char** argv) { IplImage* src=cvLoadImage("e:\\picture\\4.jpg&

winform中设置FormBorderStyle为None后点击任务栏自动最小化实现

在winform编程中,有时候我们可能对窗体样式需要定义,不适用系统自带的样式,这样我们可以设置FormBorderStyle属性为None.但是设置了FormBorderStyle为None后,我们点击任务栏应用程序图标并不能实现程序的最小化的操作(使用系统自带样式是可以实现的).下面我将展示如何在FormBorderStyle为None的情况下,实现应用程序任务栏图标点击可实现最小化. 1.添加如下代码 [DllImport("user32.dll", EntryPoint = &

oracle 自动诊断信息库(Automatic Diagnostic Repository,ADR)

ORACLE 11G中的ADR介绍: ADRCI 之oracle 日志查看 在Oracle的11g版本中,alert文件的位置发生了变化,与此同时Oracle提供了一个命令行工具ADRCI,它可以很便利的查看数据库中出现的异常. 以下给大家展示一下使用ADRCI (ADR Command Interface) 在11g中查看Oracle的警告日志的方法. 1.进入到adrci命令行模式[email protected] /home/oracle$ which adrci/oracle/u01/a

十五、自动引用计数 Automatic Reference Counting

1.Swift中的自动引用计数与Objective-C类似,如下面的例子: class Person { let name: String init(name: String) { self.name = name println("\(name) is being initialized") } deinit { println("\(name) is being deinitialized") } } 下面的代码定义了三个Person的变量,由于它们是可选类型,

人脸美白廋脸磨皮自动的化处理的一些思路(机器视觉)

分享一下思路,自己也验证过了,应该靠谱 流程 1.人脸检测加特征点定位 2.根据特征点进行廋脸之类的操作(根据定位点可以做更多好玩的东西,类似faceu的功能也可以实现) 3.美白皮肤 4.磨皮皮肤 原则上不放代码,重要的是思路 1.人脸识别用得是深度学习的方法 2.廋脸用得是http://www.gson.org/thesis/warping-thesis.pdf 3.美白用的是http://www.cnblogs.com/beibaoke/p/4779267.html 4.磨皮用得也是htt

10.1.2.1 C# 和 F# 中可重用的记忆化

如果看一下清单 10.3 中建立 add 值的代码,可以发现,它并不真正知道加法,只是使用了 addSimple 函数,因此,也可以处理其他任何函数.为了使代码更通用,我们可以把这个函数改成参数. 我们要写一个函数(C# 中叫方法),参数为函数,返回这个函数的记忆化版本.参数值是做实际工作的函数,返回的函数增加了缓存功能.清单 10.4 是C# 版本的代码. 清单 10.4 泛型记忆化方法 (C#) Func<T, R> Memoize<T,R>(Func<T, R>

6.7.3 实现列表函数

刚才我们看到的筛选和映射函数,没有展示如何实现,现在,我们要看一个在第三章开始创建的函数.因为所有的列表处理函数都有类似的结构,看过下面的示例以后,实现其他任何函数也是可能的. 在第三章,我们写的函数,能够计算列表中的所有元素的和或积:随后,我们就意识到它可能比开始所表现的更有用:我们看到,它还能用来查找最小或最大元素.那时,我们没有讨论过泛型,因此,函数只处理整数.在清单 6.22 中,有一个类似的函数,没有类型批注,原始约束自动泛型化. 清单 6.22 泛型列表聚合 (F# Interact

泛型的基本介绍和使用

在开始深入学习java的泛型了,以前一直只是在集合中简单的使用泛型,根本就不明白泛型的原理和作用.泛型在java中,是一个十分重要的特性,所以要好好的研究下. 泛 型的定义:泛型是JDK 1.5的一项新特性,它的本质是参数化类型(Parameterized Type)的应用,也就是说所操作的数据类型被指定为一个参数,在用到的时候在指定具体的类型.这种参数类型可以用在类.接口和方法的创建中,分别称为泛 型类.泛型接口和泛型方法. 泛型思想早在C++语言的模板(Templates)中就开始生根发芽,

Objective-C(十六、内存管理,自动释放池,ARC,强指针,弱指针,方法族)——iOS开发基础

结合之前的学习笔记以及参考<Objective-C编程全解(第三版)>,对Objective-C知识点进行梳理总结.知识点一直在变,只是作为参考,以苹果官方文档为准~ 十六.内存管理相关知识(二) 1.autorelease,自动释放机制 - (instancetype)autorelease; (1)自动释放池的创建 iOS5.0之前 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; //进行一系列操作 //此处不可以使用