java泛型,6.6.2 自动泛型化(automatic generalization)

6.6.2 自动泛型化(automatic generalization)
在这一章中,我们已经实现了几个 F# 中的高阶函数,看到了几个在 F# 和 C# 中并排的实现。有关 F# 实现的有趣事实是,我们根本不需要指定类型。这是由于自动泛型化(automatic generalization),它用在推断函数声明的类型。我们将用 Option.bind 函数的实现作为示例,介绍这个过程是如何工作方法的:
let bind func value =
match value with
| None –> None
| Some(a) -> func(a)
1、我们将一步一步地描述这个函数的类型推断的过程。从最通用的可能的类型开始,添加约束,因为要处理代码,所以,清单显示了处理函数体时进行的步骤。
2、使用声明签名去推断,bind 是一个函数,有两个参数值,为每个参数值和返回类型分配一个新的类型参数:
func : 't1
value : 't2
bind : 't1 -> 't2 -> 't3
3、使用模式匹配推断 value 是选项类型,因为,它是依据 Some 和 None 模式进行匹配的。使用 None –> None 推断,bind 的结果也是选项类型,因为,它可以有 None 作为一个值:
func : 't1
value : option<'t4>
bind : 't1 -> option<'t4> -> option<'t5>
4、使用 Some(a) -> func(a) 推断出,func 是一个函数,因为,我们调用它,用一个参数:
func : ('t6 -> 't7)
value : option<'t4>
bind : ('t6 -> 't7) -> option<'t4> -> option<'t5>
5、 从 Some(a) -> func(a),我们知道该函数的参数具有类型 '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# 写这样的代码不需要任何其他类型说明,而且,使代码有完全的类型安全。
有关类型推断与自动泛型化的简短插曲之后,我们还要回到写和使用高阶函数上来。第 5 章中,我们已经讨论过大多数的类型,但我们仍缺少一个重要的功能值。在下一节,我们将解决更熟悉的领域,讨论高阶函数处理列表。
Tags:  泛型方法 泛型类 泛型编程与stl 泛型编程 java泛型

延伸阅读

最新评论

发表评论