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

流行に乗る人

学習演習

はじめに

ラベル付きフィールド

カスタム型のバリアントがデータを持つとき、それはレコードと呼ばれ、含まれるそれぞれの値は_フィールド_に入ります。

pub type Rectangle {
  Rectangle(
    Float, // The first field
    Float, // The second field
  )
}

読みやすくするために、Gleamではフィールドに名前を付けてラベルを付けられます。

pub type Rectangle {
  Rectangle(
    width: Float,
    height: Float,
  )
}

ラベルを使うと、レコードのコンストラクターに引数をどのような順序でも渡せます。

let a = Rectangle(height: 10.0, width: 20.0)
let b = Rectangle(width: 20.0, height: 10.0)

a == b
// -> True

カスタム型が1つのバリアントしか持たない場合は、.labelアクセサ構文を使ってレコードのフィールドを取得できます。

let rect = Rectangle(height: 10.0, width: 20.0)

rect.height // -> 10.0
rect.width  // -> 20.0

カスタム型が単一のバリアントを持つときは、レコード更新構文を使って、既存のレコードから一部のフィールドを新しい値に置き換えた新しいレコードを作成できます。

let rect = Rectangle(height: 10.0, width: 20.0)
let tall_rect = Rectangle(..rect, height: 50.0)

tall_rect.height // -> 50.0
tall_rect.width  // -> 20.0

ラベルは、パターンマッチングでレコードから値を取り出すときにも使えます。

pub fn is_tall(rect: Rectangle) {
  case rect {
    Rectangle(height: h, width: _) if h >. 20.0 -> True
    _ -> False
  }
}

一部のフィールドだけをマッチさせたい場合は、スプレッド演算子..を使って残りのフィールドを無視できます。

pub fn is_tall(rect: Rectangle) {
  case rect {
    Rectangle(height: h, ..) if h >. 20.0 -> True
    _ -> False
  }
}

説明

この演習では、大のスポーツファンとして、NBAバスケットボールに夢中になったばかりです。NBAバスケットボールは初心者なので、NBAの歴史を深く掘り下げ、チームやコーチ、その勝敗の記録を追いかけ、互いに比較しています。

まだお気に入りのチームがないので、特定のチームを応援すべきかどうかを判断するアルゴリズムも作ることになります。

独自の_チーム応援_アルゴリズムを開発するための7つのタスクがあります。

1. モデルを定義する

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

  • name: コーチの名前。型はString。
  • former_player: コーチが元選手かどうかを示します。型はBool。

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

  • wins: 勝利数。型はInt。
  • losses: 敗北数。型はInt。

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

  • name: チームの名前。型はString。
  • coach: チームのコーチ。型はCoach。
  • stats: チームの成績。型はStats。

2. チームのコーチを作成する

コーチの名前と元選手かどうかを引数に取り、Coachレコードを返すcreate_coach関数を実装します。

create_coach("Larry Bird", True)
// -> Coach(name: "Larry Bird", former_player: True)

3. チームの成績を作成する

勝利数と敗北数を引数に取り、Statsレコードを返すcreate_stats関数を実装します。

create_stats(58, 24)
// -> Stats(wins: 58, losses: 24)

4. チームを作成する

チーム名、コーチ、成績を引数に取り、Teamレコードを返すcreate_team関数を実装します。

let coach = create_coach("Larry Bird", True)
let stats = create_stats(58, 24)
create_team("Indiana Pacers", coach, stats)
// -> Team(
//   name: "Indiana Pacers",
//   coach: Coach(name: "Larry Bird", FormerPlayer = True),
//   stats: Stats(wins: 58, losses: 24),
// ) 

5. コーチを交代させる

NBAのオーナーはせっかちなので、チームの成績が悪いとコーチが交代させられることがよくあると気づきました。チームと新しいコーチを引数に取り、新しいコーチに置き換えたチームを返すreplace_coach関数を実装します。

let coach = create_coach("Larry Bird", True)
let record = create_stats(58, 24)
let team = create_team("Indiana Pacers", coach, record)

let new_coach = create_coach("Isiah Thomas", True)
replace_coach(team, new_coach)
// -> Team(
//   name: "Indiana Pacers",
//   coach: Coach(name: "Isiah Thomas", FormerPlayer = True),
//   stats: Stats(wins: 58, losses: 24),
// ) 

6. 同じチームかどうかを確認する

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

let pacers_coach = create_coach("Larry Bird", True)
let pacers_stats = create_stats(58, 24)
let pacers_team = create_team("Indiana Pacers", pacers_coach, pacers_stats)

let lakers_coach = create_coach("Del Harris", False)
let lakers_stats = create_stats(61, 21)
let lakers_team = create_team("LA Lakers", lakers_coach, lakers_stats)

is_same_team(pacers_team, lakers_team)
// -> False

7. そのチームを応援すべきかどうかを確認する

多くのチームと試合を見てきた結果、あるアルゴリズムを考え出しました。次のいずれかに当てはまれば、そのチームを応援します。

  • コーチの名前が"Gregg Popovich"である
  • コーチが元選手である
  • チームの名前が"Chicago Bulls"である
  • チームが60試合以上勝利している
  • チームの敗北数が勝利数より多い

チームを引数に取り、そのチームを応援すべきならTrue、そうでなければFalseを返すroot_for_team関数を実装します。

let spurs_coach = create_coach("Gregg Popovich", False)
let spurs_stats = create_stats(56, 26)
let spurs_team = create_team("San Antonio Spurs", spurs_coach, spurs_stats)
root_for_team(spurs_team)
// -> True
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Gleam Exercism

流行に乗る人を始める準備はできましたか?

Exercismに登録すれば、33個のコンセプト122個の演習、そして本物の人間によるメンタリングとともに、Gleamを学んでマスターできます。すべて無料です。