This is pretty much a port from my ruby implementation, so most of what I write there about the design applies here too.
No interface was specified in the instructions for Elixir, so I made it similar to the one in Ruby:
cart = %{}
with {:ok, cart} <- Checkout.scan(cart, pricing_rules, "VOUCHER"),
{:ok, cart} <- Checkout.scan(cart, pricing_rules, "VOUCHER"),
{:ok, cart} <- Checkout.scan(cart, pricing_rules, "TSHIRT")
do
Checkout.total(cart, pricing_rules)
end
There are also tests.