三元组,5.2.3 组分使用元组

5.2.3 组分使用元组
当考虑从函数应返回什么样的元组时,关注的主要问题是可组合性(compositionally)。你期望如何使用元组?其他函数可以使用相同类型的元组吗?这符合与其余程序中的类似情况吗?
让我们使用一个示例来演示。我们将使用两种的方法,来表示以前的示例中的屏幕坐标和消息,假定已经有一个函数,打印消息。我们会省略这个实现,但是,函数 printMessage 的声明可能像这样:
> let printMessage (x, y) message =
printfn "[%d, %d] %s" x y message
;;
val printMessage : int * int -> string –> unit
这个类型签名告诉我们,该函数取两个参数值:一个包含坐标元组,一个消息。现在,我们要打印字符串"Test!"到指定的位置,由我们前面用过的元组,但它包含的消息,我们不感兴趣。清单 5.2 显示了几种方法,取决于我们使用的消息和坐标的表示。
Listing 5.2 Representations of a message with coordinates (F# Interactive)
> let msgAt1 = (50, 100, "Hello!");;
val msgAt1 : int * int * string
> let (x, y, _) = msgAt1
printMessage (x, y) "Test!";;
[50, 100] Test!
> let msgAt2 = ((50, 100), "Hello!");;
val msgAt2 : (int * int) * string
> let (coords, _) = msgAt2
printMessage coords "Test!";;
[50, 100] Test!
> printMessage (fst(msgAt2)) "Test!";;
[50, 100] Test!
如你所见,在第一种情况中所创建的元组与 printMessage 函数不兼容,因此,当我们想要组合代码时,首先要从元组中提取元素,然后,生成一个新的元组值,调用这个函数时。使用第二种表示形式,可以做得更好。元组的第一个元素本身就是一个元组,并且和 printMessage 的第一个参数兼容。
这是非常有用的,因为,当我们解构元组以后,就能取第一个元素,并将它直接用作(函数的)第一个参数值。就像最后一行所演示的,我们可以做得更好,使用 fst 函数来获得元组的第一个元素,直接调用函数。这清楚地说明为什么元组的逻辑结构很重要。此外,还需要考虑所创建的元组的复杂性。
避免复杂的元组
很明显,返回有很多元素的元组,使代码难以阅读。在 F# 中,可以用记录类型代替有太多元素的元组。记录提供了一种简单方法,创建有标记成员的类型。记录通常用于存储程序数据,所以,我们将在第 7 章谈论。
基于返回类型中元素的数目,使函数于难使用的观点,将因人而异,但我们建议避免返回的元组有三个或四个以上的元素。当然也有例外,在开发的早期阶段,使用大的元组原型可能是值得的,当对这个值的结构有了更清晰的概念以后,再进行重构。而且,如果元组仅在内部使用,较大的元组可能是更好的选项,比起声明记录类型仅使用一次要好。
既然已经知道了有关元组所需要的一切,就让我们继续。在下一节中,我们将介绍一种构建值的方法,可用于表示具有几个可选值的类型。
Tags:  数据库元组 三元组顺序表 位元组 五元组 三元组

延伸阅读

最新评论

发表评论