When a custom type variant holds data it is called a record, and each contained value resides in a field.
pub type Rectangle {
Rectangle(
Float, // The first field
Float, // The second field
)
}
To aid readability Gleam allows fields to be labelled with a name.
pub type Rectangle {
Rectangle(
width: Float,
height: Float,
)
}
Labels can be used to give arguments in any order to the constructor of a record.
let a = Rectangle(height: 10.0, width: 20.0)
let b = Rectangle(width: 20.0, height: 10.0)
a == b
// -> True
When a custom type has only one variant then the .label
accessor syntax can be used to get the fields of a record.
let rect = Rectangle(height: 10.0, width: 20.0)
rect.height // -> 10.0
rect.width // -> 20.0
The record update syntax can be used when a custom type has a single variant to create a new record from an existing one, but with some of the fields replaced with new values.
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
Labels can also be used when pattern matching to extract values from records.
pub fn is_tall(rect: Rectangle) {
case rect {
Rectangle(height: h, width: _) if h > 20.0 -> True
_ -> False
}
}
If we only want to match on some of the fields we can use the spread operator ..
to ignore any remaining fields.
pub fn is_tall(rect: Rectangle) {
case rect {
Rectangle(height: h, ..) if h > 20.0 -> True
_ -> False
}
}
In this exercise you're a big sports fan and you've just discovered a passion for NBA basketball. Being new to NBA basketball, you're doing a deep dive into NBA history, keeping track of teams, coaches, their win/loss stats, and comparing them against each other.
As you don't yet have a favorite team, you'll also be developing an algorithm to figure out whether to root for a particular team.
You have seven tasks to help you develop your proprietary root-for-a-team algorithm.
Define the Coach
record with the following two fields:
name
: the coach's name, of type String
.former_player
: indicates if the coach was a former player, of type Bool
.Define the Stats
record with the following two fields:
wins
: the number of wins, of type Int
.losses
: the number of losses, of type Int
.Define the Team
record with the following three fields:
name
: the team's name, of type String
.coach
: the team's coach, of type Coach
.stats
: the team's stats, of type Stats
.Implement the create_coach
function that takes the coach name and its former player status as parameters, and returns its Coach
record:
create_coach("Larry Bird", True)
// -> Coach(name: "Larry Bird", former_player: True)
Implement the create_stats
function that takes the number of wins and the number losses as parameters, and returns its Stats
record:
create_stats(58, 24)
// -> Stats(wins: 58, losses: 24)
Implement the create_team
function that takes the team name, coach and record as parameters, and returns its Team
record:
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),
// )
NBA owners being impatient, you found that bad team results would often lead to the coach being replaced. Implement the replace_coach
function that takes the team and its new coach as parameters, and returns the team but with the new 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),
// )
While digging into stats, you're keeping lists of teams and their records. Sometimes, you get things wrong and there are duplicate entries on your list. Implement the is_same_team
function that takes two teams and returns True
if they are the same team, otherwise, return False
:
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
Having looked at many teams and matches, you've come up with an algorithm. If one of the following is True, you root for that team:
Implement the root_for_team
function that takes a team and returns True
if you should root for that team, otherwise, return False
:
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
Sign up to Exercism to learn and master Gleam with 33 concepts, 122 exercises, and real human mentoring, all for free.