یک «رکورد» مجموعهای از فیلدهاست (که میتوانند از انواع مختلف باشند) که به هم تعلق دارند. برای تعریف یک رکورد از کلیدواژهی 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 عمیق میشوید، تیمها و مربیها و آمار برد و باختشان را دنبال میکنید و آنها را با هم مقایسه میکنید.
چون هنوز تیم محبوبی ندارید، الگوریتمی هم میسازید که مشخص کند آیا باید از یک تیم خاص هواداری کنید یا نه.
هفت کار پیش رو دارید که به شما کمک میکنند الگوریتم اختصاصی هواداری کردن از یک تیم خودتان را بسازید.
رکورد Coach را با دو فیلد زیر تعریف کنید:
Name: اسم مربی، از نوع string.FormerPlayer: نشان میدهد که مربی بازیکن پیشین بوده است یا نه، از نوع bool.رکورد Stats را با دو فیلد زیر تعریف کنید:
Wins: تعداد بردها، از نوع int.Losses: تعداد باختها، از نوع int.رکورد Team را با سه فیلد زیر تعریف کنید:
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 برمیگرداند؛ در غیر این صورت، false را return کنید:
let spursCoach = createCoach "Gregg Popovich" false
let spursStats = createStats 56 26
let spursTeam = createTeam "San Antonio Spurs" spursCoach spursStats
rootForTeam spursTeam
// => true