首页 > 代码库 > 6.7.2 理解列表函数的类型签名
6.7.2 理解列表函数的类型签名
6.7.2 理解列表函数的类型签名
前面提到过,我们使用函数来筛选和映射列表,都很直观。在本节,我们将看到它们的类型签名,知道只通过此信息,就可以推断出高阶函数能做什么。
当然,在一般情况下,不能从函数的类型就知道它能做什么,但对于泛型和高阶函数,例如那些用来处理列表的函数,通常是可能的。如我们前面所见的,处理泛型值的函数所做的不如单独处理值,因为,不能知道值的所有消息,因此,它们通常要有函数作为额外的参数值,它是用来处理这个值的。
函数的类型对结果如何使用,提供了一些线索。我们演示如何使用清单 6.20 中的类型签名。
清单 6.20 处理列表的函数和方法的签名 (F# and C#)
// F# function signatures
List.map : (‘a -> ‘b) -> ‘a list-> ‘b list <--|
List.filter : (‘a -> bool) -> ‘a list-> ‘a list | <--|
[1] |
// C# method declarations | [2]
List<B> Select<A, B>(List<A>, Func<A, B>) <--| |
List<A> Where<A>(List<A>, Func<A, bool>) <--|
让我们先看映射[1]。可以发现,输入参数是类型为 ‘a 的值的列表,结果是类型为 ‘b 的值的列表。操作不会知道 ‘b 是什么,所以,它不能单独创建此类型的值;要创建类型 ‘b 的值,唯一的方法是使用作为参数值给定的函数,把类型为 ‘a 的值转换为类型为 ‘b 的值。这表明,操作能运行的唯一合理方法,是遍历输入列表中的值,对每个值调用函数,返回结果列表。事实上,这正是映射操作所做的事。
值得注意的是,在这种情况下,输入列表的类型和输出列表的类型可以不同。在第五章,我们在整数列表中加数字 10,因此,输入列表与输出列表的类型相同。我们可以使用函数,用数字参数值创建字符串;在这种情况下,输入列表是整数列表,而结果是字符串列表。
第二个操作中筛选[2]。这里,输入和结果的列表类型相同。作为参数给定的函数,是一个判断,对于类型为 ‘a 的值,返回 true 或 false,与输入列表中元素的类型相同。这给我们一个很好的启示,操作可能为列表中的每个元素调用这个函数,并根据结果确定是否应将该元素复制到返回列表中。
6.7.2 理解列表函数的类型签名