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 選項表示的計畫的第一次發生日期。
6 3 處理計畫
6.3 處理計畫 在本節,我們要把上一節的技術應用到可選值。在處理元組時,我們發現使用函式,有助於處理元組中的元素 類似地,處理可選值時,同樣需要使用高階函式,對可選值中的乙個或多個進行某種操作。我們接著上一章的示例,從計畫型別開始,然後,看一下選項型別。在前面的章節中,我們實施了乙個表示事件計畫的...
6 3 1 處理計畫列表
6.3.1 處理計畫列表 在前面的示例中,因為我們想要列印新的計畫,因此,使用了命令式的 for 迴圈 如果想要建立包含新的計畫列表,可以使用 list.map 函式,就像這樣 let newschedules list.map fun s s mapschedule fun d d.adddays...
7 1 1 1 處理記錄
7.1.1.1 處理記錄 我們在本章後面還要用到rect 型別,有兩個簡單的函式來處理矩形。第乙個函式是縮小矩形,通過從每一條邊上減去指定的寬度和高度,第二個函式是把我們的矩形表示形式轉換成 system.drawing 命名空間中的 rectanglef 類。清單 7.2 中是這兩個函式。清單 7...