Home Posts Post Search Tag Search

Advanced Functional Elixir - 08 - Act On It
Published on: 2026-04-25 Tags: elixir, Blog, Advanced Functional Programming, FunPark, Act on It, Monoids, predicates, Monads, Maybe, Nothing

Act on It

We’ve defined a priority queue for our patrons and logic to determine whether a patron can use the FastPass lane. Now, our Ride expert wants to combine that logic, creating a priority queue for each ride’s fast lane.


This is a max monoid problem, but instead of working within the broader MaybePatron context, apply the queue inside the more refined MaybeFastPassPatron context.

  def fast_pass_lane(%Patron{} = patron, %__MODULE__{} = ride) do
    check_vip_or_pass = curry_r(&check_vip_or_fast_pass/2).(ride)

    patron
    |> check_ride_eligibility(ride)
    |> filter_map(check_vip_or_pass)
  end

Run it

iex(1)> haunted_mansion = FunPark.Ride.make("Haunted Mansion", min_age: 14)
%FunPark.Ride{
  id: 194,
  name: "Haunted Mansion",
  min_age: 14,
  min_height: 0,
  wait_time: 0,
  online: true,
  tags: []
}
iex(2)> datetime = DateTime.new!(~D[2025-06-01], ~T[13:00:00])
~U[2025-06-01 13:00:00Z]
iex(3)> fast_pass = FunPark.FastPass.make(haunted_mansion, datetime)
%FunPark.FastPass{
  id: 386,
  ride: %FunPark.Ride{
    id: 194,
    name: "Haunted Mansion",
    min_age: 14,
    min_height: 0,
    wait_time: 0,
    online: true,
    tags: []
  },
  time: ~U[2025-06-01 13:00:00Z]
}
iex(4)> alice = FunPark.Patron.make("Alice", 15, 120, reward_points: 50, ticket_tier: :premium, fast_passes: [fast_pass])
%FunPark.Patron{
  id: 450,
  name: "Alice",
  age: 15,
  height: 120,
  ticket_tier: :premium,
  fast_passes: [
    %FunPark.FastPass{
      id: 386,
      ride: %FunPark.Ride{
        id: 194,
        name: "Haunted Mansion",
        min_age: 14,
        min_height: 0,
        wait_time: 0,
        online: true,
        tags: []
      },
      time: ~U[2025-06-01 13:00:00Z]
    }
  ],
  reward_points: 50,
  likes: [],
  dislikes: []
}
iex(5)> beth = FunPark.Patron.make("Beth", 16, 130, reward_points: 20, ticket_tier: :vip)
%FunPark.Patron{
  id: 514,
  name: "Beth",
  age: 16,
  height: 130,
  ticket_tier: :vip,
  fast_passes: [],
  reward_points: 20,
  likes: [],
  dislikes: []
}
iex(6)> charles = FunPark.Patron.make("Charles", 12, 135, reward_points: 150, ticket_tier: :vip)
%FunPark.Patron{
  id: 578,
  name: "Charles",
  age: 12,
  height: 135,
  ticket_tier: :vip,
  fast_passes: [],
  reward_points: 150,
  likes: [],
  dislikes: []
}
iex(7)> all_patrons = [alice, beth, charles]
[
  %FunPark.Patron{
    id: 450,
    name: "Alice",
    age: 15,
    height: 120,
    ticket_tier: :premium,
    fast_passes: [
      %FunPark.FastPass{
        id: 386,
        ride: %FunPark.Ride{
          id: 194,
          name: "Haunted Mansion",
          min_age: 14,
          min_height: 0,
          wait_time: 0,
          online: true,
          tags: []
        },
        time: ~U[2025-06-01 13:00:00Z]
      }
    ],
    reward_points: 50,
    likes: [],
    dislikes: []
  },
  %FunPark.Patron{
    id: 514,
    name: "Beth",
    age: 16,
    height: 130,
    ticket_tier: :vip,
    fast_passes: [],
    reward_points: 20,
    likes: [],
    dislikes: []
  },
  %FunPark.Patron{
    id: 578,
    name: "Charles",
    age: 12,
    height: 135,
    ticket_tier: :vip,
    fast_passes: [],
    reward_points: 150,
    likes: [],
    dislikes: []
  }
]
iex(8)> FunPark.Ride.priority_fast_lane(all_patrons, haunted_mansion)
%FunPark.Monad.Maybe.Just{
  value: %FunPark.Patron{
    id: 514,
    name: "Beth",
    age: 16,
    height: 130,
    ticket_tier: :vip,
    fast_passes: [],
    reward_points: 20,
    likes: [],
    dislikes: []
  }
}
iex(9)> FunPark.Ride.priority_fast_lane([alice, charles], haunted_mansion)
%FunPark.Monad.Maybe.Just{
  value: %FunPark.Patron{
    id: 450,
    name: "Alice",
    age: 15,
    height: 120,
    ticket_tier: :premium,
    fast_passes: [
      %FunPark.FastPass{
        id: 386,
        ride: %FunPark.Ride{
          id: 194,
          name: "Haunted Mansion",
          min_age: 14,
          min_height: 0,
          wait_time: 0,
          online: true,
          tags: []
        },
        time: ~U[2025-06-01 13:00:00Z]
      }
    ],
    reward_points: 50,
    likes: [],
    dislikes: []
  }
}