Chap 2
Section
This notebook contains the code and exercises I type for the book https://pragprog.com/titles/jkelixir/advanced-functional-programming-with-elixir/
defprotocol Fun.Eq do
@fallback_to_any True
def eq?( a , b )
def not_eq?(a,b)
end
defimpl Fun.Eq, for: Any do
def eq?(a,b), do: a == b
def not_eq?(a,b), do: a != b
end
Patron module
defmodule Fun.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 , :fast_passes , []),
dislikes: Keyword.get(opts , :fast_passes , []),
}
end
def change(%__MODULE__{} = patron , changes) when is_map(changes) do
changes = Map.delete(changes , :id)
struct( patron, changes)
end
end
defimpl Fun.Eq, for: Fun.Patron do
alias Fun.Eq
alias Fun.Patron
def eq?( %Patron{ id: id1 } , %Patron{ id: id2} ), do: Eq.eq?(id1 , id2)
def not_eq?( %Patron{ id: id1 } , %Patron{ id: id2} ), do: Eq.not_eq?(id1 , id2)
end
Ride module
defmodule Fun.Ride do
defstruct id: nil,
name: "Unknown Ride",
min_age: 0,
min_height: 0,
wait_time: 0,
online: true,
tags: []
def make(name, opts \\ [] ) when is_binary(name) do
%__MODULE__{
name: name,
min_age: Keyword.get(opts, :min_age , 0),
min_height: Keyword.get(opts, :min_height , 0),
wait_time: Keyword.get(opts, :wait_time , 0),
online: Keyword.get(opts, :online , true),
tags: Keyword.get(opts, :tags , []),
}
end
end
Pass module
defmodule Fun.Pass do
alias Fun.Ride
defstruct id: nil,
ride: nil,
time: nil
def make( %Ride{} = ride, %DateTime{} = time) do
%__MODULE__{
id: :erlang.unique_integer([:positive]),
ride: ride,
time: time
}
end
end
Testing Things
alice = Fun.Patron.make("alice" , 15 , 100 )
alice_b = Fun.Patron.change(alice , %{ ticket_tier: :premium} )
alice == alice_b