6.6.2 自己主动泛型化(automatic generalization)

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# 中写这种代码,不须要不论什么额外的类型说明,并且代码还是全然类型安全的。

有关类型判断与自己主动泛型化的简短插曲之后。我们还要回到怎样编写和使用高阶函数上来。

在第五章,我们已经讨论了大部分类型,但仍缺少一个重要的函数式值类型;在下一节。我们将通过高阶函数处理列表,解决更熟悉的领域的问题。

posted @ 2016-01-28 16:24  mfrbuaa  阅读(162)  评论(0编辑  收藏  举报