Chapter 5: Collections
Weather ranking
- multi-clause on several arguments
- Order
compare_temperature matches on both arguments at
once. Each clause handles one combination of units, converts, and calls
itself again until both are Celsius.
list.sort(cities, _) is a function capture: the
_ marks where the piped value goes.
import gleam/float
import gleam/list
import gleam/order.{type Order}
pub type Temperature {
Celsius(Float)
Fahrenheit(Float)
}
pub type City {
City(name: String, temperature: Temperature)
}
def fahrenheit_to_celsius(fh: Float) -> Float {
fh -. 32.0 /. 1.8
}
def compare_temperature(t1: Temperature, t2: Temperature) -> Order
def compare_temperature(Fahrenheit(a), Fahrenheit(b)) {
compare_temperature(fahrenheit_to_celsius(a) |> Celsius, fahrenheit_to_celsius(b) |> Celsius)
}
def compare_temperature(Fahrenheit(a), b) {
compare_temperature(fahrenheit_to_celsius(a) |> Celsius(), b)
}
def compare_temperature(a, Fahrenheit(b)) {
compare_temperature(a, fahrenheit_to_celsius(b) |> Celsius())
}
def compare_temperature(Celsius(t1), Celsius(t2)) {
float.compare(t1, t2)
}
def sort_cities_by_temperature(cities: List(City)) -> List(City) {
fn(a: City, b: City) {
compare_temperature(a.temperature, b.temperature)
}
|> list.sort(cities, _)
}
pub def main() {
echo fahrenheit_to_celsius(72.5)
echo compare_temperature(Celsius(32.1), Celsius(21.4))
echo sort_cities_by_temperature(
[
City(name: "London", temperature: Celsius(30.5)),
City(name: "Paris", temperature: Fahrenheit(82.1))
]
)
}import gleam/float
import gleam/list
import gleam/order.{type Order}
pub type Temperature {
Celsius(Float)
Fahrenheit(Float)
}
pub type City {
City(name: String, temperature: Temperature)
}
fn fahrenheit_to_celsius(fh: Float) -> Float {
fh -. 32.0 /. 1.8
}
fn compare_temperature(arg_0: Temperature, arg_1: Temperature) -> Order {
case arg_0, arg_1 {
Fahrenheit(a), Fahrenheit(b) ->
compare_temperature(
fahrenheit_to_celsius(a) |> Celsius,
fahrenheit_to_celsius(b) |> Celsius,
)
Fahrenheit(a), b ->
compare_temperature(fahrenheit_to_celsius(a) |> Celsius(), b)
a, Fahrenheit(b) ->
compare_temperature(a, fahrenheit_to_celsius(b) |> Celsius())
Celsius(t1), Celsius(t2) -> float.compare(t1, t2)
}
}
fn sort_cities_by_temperature(cities: List(City)) -> List(City) {
fn(a: City, b: City) { compare_temperature(a.temperature, b.temperature) }
|> list.sort(cities, _)
}
pub fn main() {
echo fahrenheit_to_celsius(72.5)
echo compare_temperature(Celsius(32.1), Celsius(21.4))
echo sort_cities_by_temperature(
[
City(name: "London", temperature: Celsius(30.5)),
City(name: "Paris", temperature: Fahrenheit(82.1)),
],
)
}src/e18_weather_ranking.bea:44
54.72222222222222
src/e18_weather_ranking.bea:45
Gt
src/e18_weather_ranking.bea:46
[City("London", Celsius(30.5)), City("Paris", Fahrenheit(82.1))]An exercism exercise from the Gleam track, solved in Bea: beacode/src/e18_weather_ranking.bea