5.4.4 写泛型函数

来源:互联网 发布:出售淘宝店铺的网站 编辑:程序博客网 时间:2024/05/10 20:27

5.4.4 写泛型函数

 

能处理泛型类型的大多数函数或方法都是高阶的(higher order),就是说,它们取其他函数作为参数值。这是一个非常重要的主题,我们会专门用一整章(第六章)来讨论,但我们在还没有进入高阶领域时,就已经可以写泛型函数了。我们准备创建的函数,参数为选项类型,返回包含的值;如果选项类型不包含值,函数将触发异常。我们可以先看一下 C# 版本:

 

T ReadValue<T>(Option<T> opt) {

  Tv;

  if(opt.MatchSome(out v)) return v;

  elsethrow new InvalidOperationException();

}

 

可以发现,我们创建的泛型方法有一个类型参数,这个类型参数在方法签名中使用,既作为返回值,也作为给泛型类型 Option<T> 的参数。在方法体内,还要再次再它来声明这个类型的局部变量。总计,T 要用到四次。

这正是 F# 的类型推断真正的闪光点。看一下在 F# 中实现同样的功能,有意义的是,我们仍然不必指定任何类型:

 

> let readValue(opt) =

   matchopt with

   |Some(v) –> v

   |None -> failwith "No value!";;

val readValue : 'a option –> 'a

 

从推断出的类型签名可以发现,函数正是泛型,与 C# 版本完全一样。能够这样做的功能称为自动泛型化(automatic generalization),我们在后面会深入讨论,就现在,这里有一个 20 秒钟的描述:F# 类型推理算法搜索最通用的方法指定类型,舍弃其他一切,使用泛型类型参数。在这里,它知道参数值(opt)是选项类型,因为,我们根据 Some 和 None 识别器来匹配;还知道包含在选项类型中的函数返回值,但不知道[包含的]是哪种类型,因此,把这个类型推断为泛型类型参数。

希望这能激起了你的兴趣,能期待了解更多有关自动泛型化和高阶函数的内容,但是,我们现在先了解通常的函数式值。在其他语言中,通常不把函数当作值看待,而这正是函数编程能够如此强大而优雅的一个重要方面。

0 0
原创粉丝点击