6.3 处理计划

    技术2022-05-14  12

    6.3 处理计划

     

        在本节中,我们将把上一节的技术应用到可选为值。在处理元组时,我们发现写函数,有助于处理元组中的一个元素。同样,处理可选值时,需要高阶函数,在一个或多个可选值上执行某种操作。我们接着上一章的示例,我们从计划类型开始,然后,看一下选项类型。

        在前面的章节中,我们实施了一个类型,表示事件的计划。在 F# 中,它是叫 Schedule(计划)的差别联合,可以包含三种选项之一。可选项的三个识别器是,Never、Once 和 Repeatedly(从不,一次和多次)。在 C# 中,我们把它表示为一个抽象类 Schedule,有一个名为 tag 的属性,和一个派生类,表示三个选项的每一个。在本节中,我们会添加高阶函数,来处理计划。

        现在,假设应用程序可能会想用计划来做什么。最常用操作(尤其是在当今繁忙世界)重新安排事件。把我们知道的所有事件,推迟一周,或者把预定的事件从星期一移至星期二。明确写代码是困难的,因为,我们要为计划的三种不同类型中的每一个提供的代码。

        如果你考虑过这个问题,我们只想计算新的时间,基于原始的时间,而无需更改计划的任何其他属性。在清单 6.7 中,我们实现一个函数,它允许我们这么做。

     

    Listing 6.7 Map operation for schedule type (F# Interactive)

     

    > let mapSchedule rescheduleFunc schedule =      match schedule with      | Never -> Never      | Once(eventDate) -> Once(rescheduleFunc(eventDate))      | Repeatedly(startDate, interval) –>         Repeatedly(rescheduleFunc(startDate), interval) ;; val mapSchedule : (DateTime -> DateTime) -> Schedule –> Schedule

     

        我们称这个操作为 mapSchedule,因为,它执行某个操作,对于所有计划所包含的日期和时间信息。当一种选择是从不时,它只返回从不,而不重新计算。当是一次时,给定的函数作为一个参数值,用于计算新的时间。当计划用来表示反复时,这个函数用于计算第一次发生的新时间,保持两次发生之间原有的周期。

        如果你看一下这个类型签名,可以看到,第一个参数是一个函数,取日期时间作为参数值,并返回新的日期时间。这用于计算新的事件的时间。原计划是最后一个参数,这个参数顺序使得用流运算符调用此函数成为可能,正如我们先前用元组映射做的。清单 6.8 显示了我们如何能够使用此函数来操作计划集合。

     

    Listing 6.8 Rescheduling using the mapSchedule function (F# Interactive)

     

    > let schedules =      [ Never; Once(DateTime(2008, 1, 1));       Repeatedly(DateTime(2008, 1, 2), TimeSpan(24*7, 0, 0)) ];; val schedules : Schedule list

    > for s in schedules do      let newSchedule = s |> mapSchedule (fun d -> d.AddDays(7.0))      printfn "%A" newSchedule ;; Never Once 8.1.2008 0:00:00 Repeatedly (9.1.2008 0:00:00,7.00:00:00)

     

        我们首先创建计划的列表用来测试。注意,当构建 DateTime 和 TimeSpan 的 .NET 对象时,我们省略了 new 关键字。这只是语法的简化,F# 在处理简单类型时,是允许的,就像这两个。

        创建列表之后, 我们遍历所有的计划。在下一行中,我们使用 mapSchedule 函数来移动每一周的日程安排。日期的改变由 lambda 函数指定,返回一个新的 DateTime 对象。当然,可以实现更复杂的逻辑,在这个函数里面执行不同的重新安排。原计划是使用流运算符,作为最后一个参数值传递的。正如你可以看到的,这个操作改变了 Once 计划的日期,和使用 Repeatedly 选项表示的计划的第一次发生日期。


    最新回复(0)