Chapter 5: Collections
Wine cellar
- labelled arguments
- guards on fields
color color: Color gives the parameter an outside label
(color) and an inside name. Callers write
wines_of_color(wines, color: White), so the call reads clearly.
Clause guards can look into the matched value:
if head.color == color. Types can also be declared after
the functions that use them.
import gleam/list
def filter_by_color(wines: List(Wine), color: Color, acc: List(Wine)) -> List(Wine)
def filter_by_color([], _, acc) {
acc |> list.reverse()
}
def filter_by_color([head | tail], color, acc) if head.color == color {
filter_by_color(tail, color, [head | acc])
}
def filter_by_color([_head | tail], color, acc) {
filter_by_color(tail, color, acc)
}
pub def wines_of_color(wines: List(Wine), color color: Color) -> List(Wine) {
filter_by_color(wines, color, [])
}
def filter_by_country(wines: List(Wine), country: String, acc: List(Wine)) -> List(Wine)
def filter_by_country([], _, acc) {
acc |> list.reverse()
}
def filter_by_country([head | tail], country, acc) if head.country == country {
filter_by_country(tail, country, [head | acc])
}
def filter_by_country([_head | tail], country, acc) {
filter_by_country(tail, country, acc)
}
pub def wines_from_country(wines: List(Wine), country country: String) -> List(Wine) {
filter_by_country(wines, country, [])
}
pub def filter(wines: List(Wine), color color: Color, country country: String) -> List(Wine) {
wines
|> wines_of_color(color)
|> wines_from_country(country)
}
pub type Wine {
Wine(name: String, year: Int, country: String, color: Color)
}
pub type Color {
Red
Rose
White
}
pub def main() {
echo wines_of_color(
[
Wine("Chardonnay", 2015, "Italy", White),
Wine("Pinot grigio", 2017, "Germany", White),
Wine("Pinot noir", 2016, "France", Red),
Wine("Dornfelder", 2018, "Germany", Rose)
],
color: White
)
echo wines_from_country(
[
Wine("Chardonnay", 2015, "Italy", White),
Wine("Pinot grigio", 2017, "Germany", White),
Wine("Pinot noir", 2016, "France", Red),
Wine("Dornfelder", 2018, "Germany", Rose)
],
country: "Germany"
)
echo filter(
[
Wine("Chardonnay", 2015, "Italy", White),
Wine("Pinot grigio", 2017, "Germany", White),
Wine("Pinot noir", 2016, "France", Red),
Wine("Dornfelder", 2018, "Germany", Rose)
],
color: White,
country: "Italy"
)
}import gleam/list
fn filter_by_color(
arg_0: List(Wine),
arg_1: Color,
acc: List(Wine),
) -> List(Wine) {
case arg_0, arg_1 {
[], _ -> acc |> list.reverse()
[head, ..tail], color if head.color == color ->
filter_by_color(tail, color, [head, ..acc])
[_head, ..tail], color -> filter_by_color(tail, color, acc)
}
}
pub fn wines_of_color(wines: List(Wine), color color: Color) -> List(Wine) {
filter_by_color(wines, color, [])
}
fn filter_by_country(
arg_0: List(Wine),
arg_1: String,
acc: List(Wine),
) -> List(Wine) {
case arg_0, arg_1 {
[], _ -> acc |> list.reverse()
[head, ..tail], country if head.country == country ->
filter_by_country(tail, country, [head, ..acc])
[_head, ..tail], country -> filter_by_country(tail, country, acc)
}
}
pub fn wines_from_country(
wines: List(Wine),
country country: String,
) -> List(Wine) {
filter_by_country(wines, country, [])
}
pub fn filter(
wines: List(Wine),
color color: Color,
country country: String,
) -> List(Wine) {
wines |> wines_of_color(color) |> wines_from_country(country)
}
pub type Wine {
Wine(name: String, year: Int, country: String, color: Color)
}
pub type Color {
Red
Rose
White
}
pub fn main() {
echo wines_of_color(
[
Wine("Chardonnay", 2015, "Italy", White),
Wine("Pinot grigio", 2017, "Germany", White),
Wine("Pinot noir", 2016, "France", Red),
Wine("Dornfelder", 2018, "Germany", Rose),
],
color: White,
)
echo wines_from_country(
[
Wine("Chardonnay", 2015, "Italy", White),
Wine("Pinot grigio", 2017, "Germany", White),
Wine("Pinot noir", 2016, "France", Red),
Wine("Dornfelder", 2018, "Germany", Rose),
],
country: "Germany",
)
echo filter(
[
Wine("Chardonnay", 2015, "Italy", White),
Wine("Pinot grigio", 2017, "Germany", White),
Wine("Pinot noir", 2016, "France", Red),
Wine("Dornfelder", 2018, "Germany", Rose),
],
color: White,
country: "Italy",
)
}src/e19_wine_cellar.bea:56
[Wine("Chardonnay", 2015, "Italy", White), Wine("Pinot grigio", 2017, "Germany", White)]
src/e19_wine_cellar.bea:66
[Wine("Pinot grigio", 2017, "Germany", White), Wine("Dornfelder", 2018, "Germany", Rose)]
src/e19_wine_cellar.bea:76
[Wine("Chardonnay", 2015, "Italy", White)]An exercism exercise from the Gleam track, solved in Bea: beacode/src/e19_wine_cellar.bea