15.6.2 定义基元

15.6.2 定义基元

首先要定义将要处理的值类型,然后,实现几个可以在以后组合的基元。基元数据类型叫 Contract,表示可能出现在特定日期和时间的交易。

声明 CONTRACT 类型

你可以看到在清单 15.23 中,Contract 类型与动画示例中的行为类型很相似,它是一个差别联合,只有一个识别器,名为 ContractFunc。这是我们一直在使用一种技巧,当定义行为时,它给了我们一种方法,可以创建简单、命名和封装的函数值。

Listing 15.23 Type representing financial contracts (F# Interactive)

> type Contract =
| ContractFunc of (DateTime -> seq<string * int>);;
(...)
> let eval_r(ContractFunc f) dt = f(dt) |> List.ofSeq;;
val eval : Contract -> DateTime -> (string * int) list

此函数表示实际合同带有一个参数,并返回一个元组序列。当我们用特定的日期调用它时,将生成所有发生在该日期的交易。每笔交易表示为一个元组,包含股票的名称和想要购买或出售的股票数量。我们将用正数表示购买股票数量,负数表示出售数量。

清单15.23 的第二部分实现 eval 函数,计算在给定时间的合同,并返回的列表。我们使用一个序列来表示中的合同,因为,这会使代码更通用。我们看到动态生成序列并组合它们,是多么容易。Eval 函数返回一个列表,因为,从调用者的角度来看,更容易地处理。

实现组合

有了表示我们的语言值的数据类型以后,就需要实现几个基本函数,来创建和组合这些值。对于行为,我们创建了基元值,比如,wiggle,和提升运算符来组合它们。在我们的合同语言中,从函数 trade 开始,创建一个表示可以发生在任何时间的购买合同。要组合合同,需要提供函数 combine,它把两份不同的合同加到这个交易中。

清单 15.24 显示了这两个函数的实现,以及对于限定日期可能发生的合同的函数,和创建由合同所代表的我们准备出售股票交易的函数。

Listing 15.24 Combinators for creating and composing contracts (F# Interactive)

> let trade what amount = ContractFunc(fun _ –>
seq { yield what, amount })
let combine (ContractFunc a) (ContractFunc b) =
ContractFunc(fun now –>
Seq.concat [ a(now); b(now) ])
;;
val trade : int -> string -> Contract
val combine : Contract -> Contract –> Contract

> let after dt (ContractFunc f) = ContractFunc(fun now –>
seq { if now >= dt then yield! f(now) })
let until dt (ContractFunc f) = ContractFunc(fun now –>
seq { if now <= dt then yield! f(now) })
let sell (ContractFunc f) = ContractFunc(fun now –>
seq { for itm, am in f(now) -> itm, -am })
;;
val after : DateTime -> Contract -> Contract
val until : DateTime -> Contract -> Contract
val sell : Contract –> Contract

可以在任何时间发生的单笔交易被表示为一个函数,将忽略其参数(我们计算合同的日期),并返回只有一个元素的序列。组合也简单,因为我们连接发生在给定日期的两个基础合同下所有的交易。

接下来两个基元,在限定日期哪些合同是活动的。其实现是通过创建一个函数,测试给定的日期是否匹配基元的条件。当测试成功时,返回所有基础交易,使用 yield! 基元;否则,返回一个空序列。最后的基元可以用于修改合约是出售还是购买。 我们遍历一个合同的所有基础交易,把正的数量改为负,或相反。

虽然我们只是大概地勾画出这个库,但已经实现的几个基元就能够描述许多有趣的情景了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值