轨道
/
F#
F#
/
练习
/
跟风者
跟风者

跟风者

学习练习

简介

记录

记录是一组字段的集合,这些字段可以有不同的类型,但彼此关联。定义记录要使用 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 个任务,帮你打磨出属于你自己的_支持球队_算法。

1. 定义模型

定义Coach记录,它包含以下 2 个字段:

  • Name:教练的姓名,类型为string。
  • FormerPlayer:表示教练是否为前球员,类型为bool。

定义Stats记录,它包含以下 2 个字段:

  • Wins:胜场数,类型为int。
  • Losses:负场数,类型为int。

定义Team记录,它包含以下 3 个字段:

  • Name:球队名称,类型为string。
  • Coach:球队的教练,类型为Coach。
  • Stats:球队的数据,类型为Stats。

2. 创建球队的教练

实现createCoach函数,它接收教练姓名和其是否为前球员作为形参,并返回对应的Coach记录:

createCoach "Larry Bird" true
// => { Name = "Larry Bird"; FormerPlayer = true }

3. 创建球队的数据

实现createStats函数,它接收胜场数和负场数作为形参,并返回对应的Stats记录:

createStats 58 24
// => { Wins = 58; Losses = 24 }

4. 创建球队

实现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 } }

5. 更换教练

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 } }

6. 检查是否为同一支球队

在钻研各种数据时,你会把球队和它们的记录整理成列表。有时你会弄错,列表里就出现了重复的条目。实现isSameTeam函数,它接收 2 支球队,如果它们是同一支球队就返回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

7. 判断是否该支持某支球队

看过许多球队和比赛之后,你想出了一个算法。只要满足下面任意一条,你就支持这支球队:

  • 教练的名字是“Gregg Popovich”
  • 教练是前球员
  • 球队的名字是“Chicago Bulls”
  • 球队赢过 60 场或更多比赛
  • 球队的负场多于胜场

实现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
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
F# Exercism

准备好开始 跟风者 了吗?

注册 Exercism,借助 18 个概念148 个练习 和真人导师指导,学习并掌握 F#,全部免费。