概述
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! 基元;否则,返回一个空序列。最后的基元可以用于修改合约是出售还是购买。 我们遍历一个合同的所有基础交易,把正的数量改为负,或相反。
虽然我们只是大概地勾画出这个库,但已经实现的几个基元就能够描述许多有趣的情景了。
最后
以上就是谦让棒棒糖为你收集整理的15.6.2 定义基元的全部内容,希望文章能够帮你解决15.6.2 定义基元所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复