トラック
/
F#
F#
/
演習
/
流行に乗る人
流行に乗る人

流行に乗る人

学習演習

はじめに

レコード

レコードは、互いに関連するフィールド(それぞれ異なる型でもかまいません)をまとめたものです。レコードを定義するには、typeキーワードを使います。レコードのフィールドは{と}の間に定義し、各フィールドには名前_と_型の両方を指定します。レコードを作成するには、フィールドの名前を指定し、{と}の間に値を代入します。レコードを作成するときは、すべてのフィールドに値を代入しなければなりません。レコードのインスタンスのフィールドの値には、ドット記法でアクセスできます。

レコードを定義・作成するときは、各フィールドを別々の行に書くか、1行にまとめる場合はセミコロン(;)で区切ります。

// 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キーワードを使うと、既存のレコードのコピーを、1つ以上のフィールドに新しい値を設定した状態で作成できます。

// Copy the old address but change the house number
let newAddress: Address = { oldAddress with HouseNumber = 86 }
newAddress.Street      // => "Main Street"
newAddress.HouseNumber // => 86

レコードには_構造的等価性_があります。つまり、同じレコードの2つのインスタンスは、値がまったく同じであれば等しいとみなされます。

ドット記法でレコードのフィールドにアクセスできるだけでなく、レコードは束縛やパターンマッチングの中で_分解_することもできます。

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. モデルの定義

次の2つのフィールドを持つCoachレコードを定義します。

  • Name:コーチの名前(型はstringです)。
  • FormerPlayer:コーチが元選手だったかどうかを示します(型はboolです)。

次の2つのフィールドを持つStatsレコードを定義します。

  • Wins:勝ち数(型はintです)。
  • Losses:負け数(型はintです)。

次の3つのフィールドを持つTeamレコードを定義します。

  • Name:チームの名前(型はstringです)。
  • Coach:チームのコーチ(型はCoachです)。
  • Stats:チームの成績(型はStatsです)。

2. チームのコーチの作成

コーチの名前と元選手かどうかを入力として受け取り、Coachレコードを返すcreateCoach関数を実装します。

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

3. チームの成績の作成

勝ち数と負け数を入力として受け取り、Statsレコードを返すcreateStats関数を実装します。

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

4. チームの作成

チーム名、コーチ、成績のレコードを入力として受け取り、Teamレコードを返すcreateTeam関数を実装します。

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. 同じチームかどうかの確認

成績を調べているうちに、チームとその成績のリストを作っています。ときどき間違えて、リストに重複した項目が入ってしまうことがあります。2つのチームを受け取り、同じチームならtrueを、そうでなければfalseを返すisSameTeam関数を実装します。

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試合以上勝っている
  • チームの負け数が勝ち数より多い

チームを受け取り、そのチームを応援すべきならtrueを、そうでなければreturnでfalseを返すrootForTeam関数を実装します。

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#を学んでマスターできます。すべて無料です。