2013-10-11 131 views
2

如何在記錄上進行模式匹配還有更習慣用法嗎?我的代碼看起來不正確。F#記錄中的模式匹配

type Period = AM | PM 

type TimeOfDay = {hours : int; minutes : int; p : Period} 

let before (tod1 : TimeOfDay, tod2 : TimeOfDay) = 
    match tod1, tod2 with 
    | {hours = h1; minutes = m1; p = AM}, {hours = h2; minutes = m2; p = AM} -> (h1, m1) < (h2, m2) 
    | {hours = h1; minutes = m1; p = PM}, {hours = h2; minutes = m2; p = PM} -> (h1, m1) < (h2, m2) 
    | {hours = _; minutes = _; p = AM}, {hours = _; minutes = _; p = PM} -> true 
    | {hours = _; minutes = _; p = PM}, {hours = _; minutes = _; p = AM} -> false 
+5

如果移動'Period'是在'TimeOfDay',然後'TimeOfDay'值的第一場會自然排序的順序,你期望的,所以你可以用'tod1

+3

如果由於某種原因你不能重新排序記錄字段(例如,如果它們來自外部庫),你仍然可以執行'(tod1.p,tod1.hours,tod1.minutes)<(tod2.p,tod2 .hours,tod2.minutes)'。 – Tarmil

+1

或者,您可以切換到24h時間:'let adjust = function | {小時= H;分鐘=米; p = PM} - > {小時= h + 12;分鐘=米; p = AM} |然後比較這個函數對兩條記錄的應用結果:'let before(tod1,tod2)= adjust tod1 bytebuster

回答

4

你可以做一個稍有好轉,你並不需要表現出不需要的圖案產生以下

let before (tod1 : TimeOfDay, tod2 : TimeOfDay) = 
    match tod1, tod2 with 
    | {hours = h1; minutes = m1; p = AM}, {hours = h2; minutes = m2; p = AM} -> (h1, m1) < (h2, m2) 
    | {hours = h1; minutes = m1; p = PM}, {hours = h2; minutes = m2; p = PM} -> (h1, m1) < (h2, m2) 
    | { p = AM}, {p = PM} -> true 
    | { p = PM}, {p = AM} -> false 

接下來,你可以定義一個Active模式解構型成一個元組爲如下

let (|TIME|) (t:TimeOfDay) = t.hours,t.minutes,t.p 

let before (tod1 : TimeOfDay, tod2 : TimeOfDay) = 
    match tod1, tod2 with 
    | TIME(h1,m1,AM), TIME(h2,m2,PM) -> (h1, m1) < (h2, m2) 
    | TIME(h1,m1,PM), TIME(h2,m2,PM) -> (h1, m1) < (h2, m2) 
    | { p = AM}, {p = PM} -> true 
    | { p = PM}, {p = AM} -> false