記錄是一組彼此相關的欄位集合(這些欄位可以有不同的型別)。要定義記錄,會使用type關鍵字。記錄的欄位定義在{和}字元之間,每個欄位都有名稱,也有型別。要建立記錄,就在{和}字元之間指定欄位的名稱並指派值給它們。建立記錄時,所有欄位都必須指派值。記錄實例的欄位值可以用點記法存取。
定義或建立記錄時,每個欄位必須各自獨立一行,或在同一行時以分號(;)分隔。
// Define a record
type Address =
{ Street: string
HouseNumber: int }
// Create a record
let oldAddress: Address =
{ Street = "Main Street"
HouseNumber = 17 }
// Single-line alternative
type ConciseAddress = { Street: string; HouseNumber: int }
let conciseAddress: ConciseAddress = { Street = "Main Street"; HouseNumber = 17 }
由於記錄是不可變的,一旦記錄被建構出來,它的欄位值就永遠不會改變。如果你想改變記錄的值,with關鍵字可以讓你建立現有記錄的複本,但其中一個或多個欄位會採用新的值。
// Copy the old address but change the house number
let newAddress: Address = { oldAddress with HouseNumber = 86 }
newAddress.Street // => "Main Street"
newAddress.HouseNumber // => 86
記錄具有_結構相等性_,意思是同一個記錄的兩個實例只要值完全相同,就是等值的。
除了能用點記法存取記錄的欄位之外,記錄也可以在綁定和模式比對中_解構_:
let myAddress: Address = { Street = "Broadway"; HouseNumber = 123 }
let { Street = myStreet; HouseNumber = myHouseNumber } = myAddress
match myAddress with
| { HouseNumber = 1 } -> printfn "First house"
| { HouseNumber = houseNumber; Street = street } -> printfn "House number %d on %s" houseNumber street
// => "House number 123 on Broadway
在這個練習中,你是個超級運動迷,而且你最近剛愛上 NBA 籃球。因為剛接觸 NBA 籃球,你正深入鑽研 NBA 的歷史,追蹤各支球隊、教練和他們的勝敗戰績,並互相比較。
由於你還沒有最喜歡的球隊,你也會開發一套演算法,判斷是否該支持某支球隊。
你有 7 個任務,幫助你開發專屬於你的支持球隊演算法。
定義Coach記錄,包含以下 2 個欄位:
Name:教練的名字,型別為string。FormerPlayer:指出這位教練是否為前球員,型別為bool。定義Stats記錄,包含以下 2 個欄位:
Wins:勝場數,型別為int。Losses:敗場數,型別為int。定義Team記錄,包含以下 3 個欄位:
Name:球隊的名字,型別為string。Coach:球隊的教練,型別為Coach。Stats:球隊的戰績,型別為Stats。實作createCoach函式,接受教練的名字和是否為前球員的狀態作為參數,並回傳它的Coach記錄:
createCoach "Larry Bird" true
// => { Name = "Larry Bird"; FormerPlayer = true }
實作createStats函式,接受勝場數和敗場數作為參數,並回傳它的Stats記錄:
createStats 58 24
// => { Wins = 58; Losses = 24 }
實作createTeam函式,接受球隊名字、教練和記錄作為參數,並回傳它的Team記錄:
let coach = createCoach "Larry Bird" true
let record = createStats 58 24
createTeam "Indiana Pacers" coach record
// => { Name = "Indiana Pacers"
// Coach = { Name = "Larry Bird"; FormerPlayer = true }
// Stats = { Wins = 58; Losses = 24 } }
NBA 球隊老闆們沒什麼耐心,你發現球隊戰績不佳時,教練往往會被換掉。實作replaceCoach函式,接受球隊和它的新教練作為參數,並回傳換上新教練之後的球隊:
let coach = createCoach "Larry Bird" true
let record = createStats 58 24
let team = createTeam "Indiana Pacers" coach record
let newCoach = createCoach "Isiah Thomas" true
replaceCoach team newCoach
// => { Name = "Indiana Pacers"
// Coach = { Name = "Isiah Thomas"; FormerPlayer = true }
// Stats = { Wins = 58; Losses = 24 } }
在深入鑽研戰績的過程中,你會整理一份份球隊和它們戰績的清單。有時候你會弄錯,清單上就會出現重複的項目。實作isSameTeam函式,接受兩支球隊,如果它們是同一支球隊就回傳true;否則回傳false:
let pacersCoach = createCoach "Larry Bird" true
let pacersStats = createStats 58 24
let pacersTeam = createTeam "Indiana Pacers" pacersCoach pacersStats
let lakersCoach = createCoach "Del Harris" false
let lakersStats = createStats 61 21
let lakersTeam = createTeam "LA Lakers" lakersCoach lakersStats
isSameTeam pacersTeam lakersTeam
// => false
看過許多球隊和比賽之後,你想出了一套演算法。只要符合下列其中一項,你就支持那支球隊:
實作rootForTeam函式,接受一支球隊,如果你應該支持該球隊就回傳true;否則return false:
let spursCoach = createCoach "Gregg Popovich" false
let spursStats = createStats 56 26
let spursTeam = createTeam "San Antonio Spurs" spursCoach spursStats
rootForTeam spursTeam
// => true