Skip to content

Instantly share code, notes, and snippets.

@JEG2
Created March 14, 2026 22:16
Show Gist options
  • Select an option

  • Save JEG2/658ffab4aacf1e9b0ee3224edb7ff47a to your computer and use it in GitHub Desktop.

Select an option

Save JEG2/658ffab4aacf1e9b0ee3224edb7ff47a to your computer and use it in GitHub Desktop.
My suggested rewrite of a composable sorting example from Advanced Functional Programming in Elixir.
defmodule FunPark.Patron do
defstruct id: nil,
name: nil,
age: 0,
height: 0,
ticket_tier: :basic,
fast_passes: [],
reward_points: 0,
likes: [],
dislikes: []
def make(name, age, height, opts \\ [])
when is_bitstring(name) and
is_integer(age) and
is_integer(height) and
age > 0 and
height > 0 do
%__MODULE__{
id: :erlang.unique_integer([:positive]),
name: name,
age: age,
height: height,
ticket_tier: Keyword.get(opts, :ticket_tier, :basic),
fast_passes: Keyword.get(opts, :fast_passes, []),
reward_points: Keyword.get(opts, :reward_points, 0),
likes: Keyword.get(opts, :likes, []),
dislikes: Keyword.get(opts, :dislikes, [])
}
end
def tier_priority(%__MODULE__{ticket_tier: :vip}), do: 3
def tier_priority(%__MODULE__{ticket_tier: :premium}), do: 2
def tier_priority(%__MODULE__{ticket_tier: :basic}), do: 1
def tier_priority(%__MODULE__{ticket_tier: _}), do: 0
end
alice =
FunPark.Patron.make(
"Alice",
15,
50,
reward_points: 50,
ticket_tier: :premium
)
beth =
FunPark.Patron.make(
"Beth",
16,
55,
reward_points: 20,
ticket_tier: :vip
)
charles =
FunPark.Patron.make(
"Charles",
14,
60,
reward_points: 50,
ticket_tier: :premium
)
patrons = [charles, beth, alice]
patrons
|> Enum.sort_by(fn p ->
[FunPark.Patron.tier_priority(p), p.reward_points, p.name]
end)
|> IO.inspect()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment