15.1.3 可组合值

15.1.3 可组合值

把问题描述为值,是把"语言"嵌入 F# 中的最简单的方法。这仅适用于简单的问题:我们不要指定任何复杂行为(比如,过滤函数的断言) ,和只需要通过组合基元对象或集合,并指定它们的属性,就能描述的大多数的问题。

当代码有效地描述值时,我们可以在 F# 中实现它,通过创建类型,能够创建指定所有属性的值。表示这类问题的最常见的 F# 类型,是差别联合,对于有大量属性的基元,也可以使用列表(表示项的集合),或记录。清单 15.1 显示一个简单的类型声明,与前面 LISP 中示例同样的动画。

Listing 15.1 Specifying animations using discriminated unions (F#)

type AnimatedLocation =
| Static of PointF
| Rotating of PointF * float32
| Linear of PointF * PointF

type Animation =
| Disc of Brush * int * AnimatedLocation
| Compose of Animation * Animation

使用这个类型,我们现在可以创建描述简单动画的值。从某种意义上讲,清单 15.1 中的类型指定的语法,也用于创建动画的库,因为它指定了什么是有效的动画值。下面的代码片断显示在 LISP 中相同的动画效果:

let animation =
Compose(
Disc(Brushes.Green, 50, Rotating(PointF(0.f,0.f), 100.f)),
Disc(Brushes.Red, 20, Linear(PointF(-100.f,0.f), PointF(100.f,0.f)))
)

这段代码创建一个树状结构的值,描述由两个盘子组成的动画。它指定每个对象如何随时间而改变位置,F# 的数据结构 AnimatedLocation 创建的对象是静态的,可以旋转,或沿着一条直线移动。

当在 C# 中使用这种方法时,可以把这个差别联合类型重写为类层次。然后,通过创建一个对象树,获得类似的结果。在 C# 3.0 中,这由对象和集合初始值设定项功能,做了进一步简化:

var animation = new Compose(
new Disc { Brush = Brushes.Green, Diameter = 50, Movement =
new Rotating(new PointF(0.0f,0.0f), 100.0f) },
new Disc { Brush = Brushes.Red, Diameter = 20, Movement =
new Linear(new PointF(-100.0f, 0.0f), new PointF(100.0f, 0.0f) } }
);

原理是相同的:声明性的库用于创建描述问题的值。在差别联合或集合和对象之间的选择,在很大程度上受语法影响,使得可以在宿主语言中创建最自然的代码。

构建数据结构,这基本上是描述动画的消极方式。我们要看一种技术,使代码有更积极的感觉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值