Chapter 3: Your own types

Bird count

  • recursion
  • clause guards

Multi-clause functions can have guards. In has_day_without_birds, the second clause only applies if head == 0; otherwise matching falls through to the next clause.

Notice that today and increment_day_count need no type annotations at all. Gleam infers them from the patterns.

Open in playground
import gleam/int
import gleam/list

def today([]) {
  0
}

def today([head | _]) {
  head
}

def increment_day_count([]) {
  [1]
}

def increment_day_count([head | tail]) {
  [head + 1 | tail]
}

def has_day_without_birds(days: List(Int)) -> Bool

def has_day_without_birds([]) {
  False
}

def has_day_without_birds([head | _tail]) if head == 0 {
  True
}

def has_day_without_birds([_head | tail]) {
  has_day_without_birds(tail)
}

def total(days: List(Int)) -> Int {
  int.sum(days)
}

def busy_days(days: List(Int)) -> Int {
  days
  |> list.count(fn(x) {x >= 5})
}

pub def main() {
  echo today([2, 5, 1])
  echo increment_day_count([4, 0, 2])
  echo has_day_without_birds([3, 8, 1, 0])
  echo total([4, 0, 9, 0, 5])
  echo busy_days([4, 5, 0, 0, 6])
}

An exercism exercise from the Gleam track, solved in Bea: beacode/src/e11_bird_count.bea