您的位置:首页 > 编程语言 > C语言/C++

关于学习C++和编程的50个观点

2009-08-29 10:10 218 查看
15.3.2 将函数应用到行为
 
    在早先描述行为时,我们解释过,行为是一个复合值,相似性在于 Behavior<int> 和 Option<int> 之间。两者都是包含另一个值的复合值,但有不同的方式。选项类型的不寻常,在于它可能为空,而行为的不寻常,在于值依时间而变。
    这个比喻表明行为的方向。我们已经看到,Option.map 在几个不同的上下文中,指定的函数应用到由该选项携带的值的能力,是正是我们在行为系统所寻找的。清单 15.8 为行为创建了类似 map 的函数,演示如何用它实现简单的"时间平方"的行为。
 
Listing 15.8 Implementing map for behaviors (F# Interactive)
 
> module Behavior =
     let map f (BehaviorFunc bfunc) =
       sample(fun t -> f(bfunc(t)));;
module Behavior =
val map : ('a -> 'b) -> Behavior<'a> -> Behavior<'b>
> let squared = time |> Behavior.map (fun n -> n * n);;
val squared : Behavior<float32>
> squared |> readValue 9.0f;;
val it : float32 = 81.0f
 
    函数 map 在一个模块内声明,遵循标准的命名模式。Behavior.map 的第一个参数是我们想要应用到行为值的函数 (f),第二个参数是行为本身,我们再提取函数下面的内容,使用模式匹配表示(bfunc) 。为了构建结果,我们需要创建一个新的行为,所以,构建其基础表示,就是一个函数。我们使用 lambda 函数,它取时间作为参数。它首先运行 bfunc,获取那时原来行为的值,然后,运行 f 函数,获得最终的结果。事实上,主体就是由几个函数组成,所以,也可以把这个实现写成 sample(bfunc >> f)。在清单 15.8 中,我们使用一个 lambda 函数,使代码更加明确,但当你使用函数式代码一段时间以后,就会发现,在这种情况下,函数组合更易于使用,更可读。
    我们现在可以使用 Behavior.map 对这个行为所携带的值执行任何计算。第二个命令显示,我们可以计算出其他基元行为的平方。我们作为结果得到的行为,直到要求它计算在指定的时间的实际值时,才执行平方函数。当我们这样做了,它就执行这个函数,从 map 函数返回作为结果。此函数获取当前时间,通过计算原来行为的值(这里,是 time 基元)。然后,它将运行我们提供的平方函数。
    组合库的总目标是提供一种方法来描述问题,通过组合其他基元而不是写程序来解决问题。就像这个示例中 Behavior.map 函数一样,发挥了关键作用,因为它们表达了易于理解的概念(比如映射),当我们写声明性描述问题时,可以使用。我们很快就会看到,可以使用 map 函数,在设计时,并不认为它是非常有用的方法。
    我们取得了很大的进步:现在可以拿一个基元行为,进行几乎任何计算,构建出更复杂的行为。我们现在可以实现 wiggle 基元,只是通过将正弦函数,使用 map,应用于 time 基元。 还有一些不能很容易做的事情。如果我们想要添加两种行为,又该如何做呢?有比使用 sample 基元更优雅的方式吗?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: